依赖注入中接口的C#名称空间
我想在C#中使用依赖注入中接口的C#名称空间,c#,dependency-injection,interface,namespaces,dependencies,C#,Dependency Injection,Interface,Namespaces,Dependencies,我想在C#中使用依赖注入模式,并且我想在名称空间中尽可能地分离逻辑 问题: 所使用类的接口应该在哪个命名空间中 问题的动机 首先让我们做一些“正常”的案例。作为第二部分解释的基础的书箱。然后,“现实生活”案例,这就产生了问题 书柜 让我们假设编码者是Alice,并且她使用Alice作为供应商在名称空间中作为顶级名称,以避免与其他编码者发生冲突。在本例中,我们假设世界上没有其他Alice 假设她创建了3个名称空间: 爱丽丝.入侵者——一款通过商店提供应用内购买的游戏 Alice.Shop-一个可
依赖注入
模式,并且我想在名称空间中尽可能地分离逻辑
问题:
所使用类的接口
应该在哪个命名空间中
问题的动机
首先让我们做一些“正常”的案例。作为第二部分解释的基础的书箱。然后,“现实生活”案例,这就产生了问题
书柜
让我们假设编码者是Alice,并且她使用Alice
作为供应商在名称空间中作为顶级名称,以避免与其他编码者发生冲突。在本例中,我们假设世界上没有其他Alice
假设她创建了3个名称空间:
——一款通过商店提供应用内购买的游戏爱丽丝.入侵者
-一个可重复使用的商店,用于多种游戏Alice.Shop
-可重用的服务管理器Alice.Injector
Shop
项目有一个名为IShopService
的接口,该接口提供了一个方法Show()
让我们假设,入侵者
有某种控制器,在某些用户操作中,它想要打开商店
让我们假设服务,如商店
,是由入侵者的控制器通过服务管理器
获得的
艾丽斯,注射器
Alice.Injector
本身是一个没有依赖关系的独立项目,因此它不使用“using”关键字:
爱丽丝,去商店
Alice.Shop
也是一个独立的项目,它(除使用服务的情况外)不知道喷油器的存在。只是一家商店而已
由于Alice认为Bob将来可能会做得更好,因此她准备将类注入依赖项,将shop
分离为接口IShop
,然后实现,如下本文所示:
为了实现这一点,Alice将使商店成为一种与Alice.ServiceManager
兼容的服务类型,因此Alice决定将IShop
重命名为IShopService
,它将是一种IService
using Alice.Injector
namespace Alice.Shop
{
public interface IShopService : IService
{
public void Show();
}
public class Shop : IShopService
{
public void Show()
{
// Here Alice puts all the code to open the shop up.
}
}
}
爱丽丝,入侵者
最后,爱丽丝编写了游戏代码。Alice.investors
的代码通过ServiceManager
获得一个Shop
(以服务的形式),因此它是干净的代码
using Alice.Injector
using Alice.Shop
namespace Alice.Invaders
{
public class DefaultController
{
void OnShopClick()
{
IShopService shop = ServiceManager.Get( "Shop" ) as IShopService;
shop.Show();
}
}
}
到目前为止,一切都很顺利
真实案例
所以现在。。。鲍勃(大家都知道,他是爱丽丝的好朋友,很好奇他们今天不谈论发送加密信息),开了一家超级不错的商店,比爱丽丝开的那家店还要好。鲍勃从头做起
因此Bob实现了与Alice的injector兼容的商店(Bob也使用Alice.injector
在他的项目中注入其他东西)
所以。。。这就是奇怪的情况
Bob.Shop
接口的名称空间-如果Bob按照上面显示的方式在Bob.Shop
名称空间内购物,那么Alice必须编辑她的代码以引用Bob.Shop
,以获得IShopService
接口(她必须更改代码中的依赖项,因为应该使用依赖项注入器来摆脱更改代码中的依赖项)
- 接口没有名称空间-如果Alice和Bob都在全局名称空间中设置了
IShopService
,那么它也很难看,因为那里有很多东西可能会冲突
Alice.Shop
接口的名称空间-如果Bob利用常识说“我想做的是创建一个与Alice的商店兼容的商店,那么我应该实现她的接口”,那么Bob的代码很可能如下所示:
Bob的代码使用Alice.Shop
向后命名空间兼容性:
namespace Bob.Shop
{
public class Shop : Alice.Shop.IShopService
{
public void Show()
{
// Here Bob does a brand new shop from scratch,
// which borrows Alice's interface.
}
}
}
在这种情况下,似乎一切就绪:
- Bob可以创建实现Alice.Shop.IShopService的
Bob.Shop.Shop
- Alice不需要更改一行代码
Alice.Injector.ServiceManager
能够在为Bob.Shop.Shop
提供服务时提供另一个iSeries设备
问题
这里仍然有一个依赖关系:
Alice.investors
正在将Alice.Injector.IService
强制转换为Alice.Shop.IShopService
,以便能够调用Show()
方法。如果不执行该强制转换,则无法“显示商店”
因此,在最后,您将“依赖”该类型转换,因此“某人”需要向您提供接口定义
如果最初的shop不是Alice写的,而是Charlie写的,那么为了使用Bob.shop
,还必须下载并保存Charlie.shop
项目的副本将是“丑陋的”
所以
问题
1) IShopInterface
的正确名称空间是什么
2) “替换”项目是否提供自己的接口或借用原始接口
3) 是否应该将原来的商店分成两个项目?(例如Alice.Shop
和Alice.ShopImplementation
因此Alice.Shop
非常纤细,只包含接口?可能Alice.Shop
和Alice.Shop.Implementation
作为嵌套名称空间,但仍然有两个独立的代码库,因此您可以下载ans安装Alice.Shop
)正在下载Alice.Shop.Implementation
4) 这是否像Bob在他的项目中包含Alice.Shop.IShopInterface
文件的副本那样简单,因此不需要依赖项?非常难看-如果他这么做了,我们想拥有2家商店和
using Alice.Injector
namespace Bob.Shop
{
public interface IShopService : IService
{
public void Show();
}
public class Shop : IShopService
{
public void Show()
{
// Here Bob does a brand new shop from scratch.
}
}
}
namespace Bob.Shop
{
public class Shop : Alice.Shop.IShopService
{
public void Show()
{
// Here Bob does a brand new shop from scratch,
// which borrows Alice's interface.
}
}
}
public class DefaultController
{
private readonly IShopService _shopService;
DefaultController(IShopService shopService)
{
_shopService=shopService;
}
void OnShopClick()
{
_shopService.Show();
}
}