我尝试使用像Ninject这样的IoC来设计WebApi应用程序。我有以下几层(3个项目):
Repository层具有接口IRepository<T>
及其一些实现。并且在服务中还存在具有两种不同实现的接口IService<T>
。
如果我在WebApi项目中使用DI容器(Ninject)绑定IService<T>
和ServiceConcrete<T>
以及服务项目中的DI容器来绑定IRepository<T>
和{{1>,请告诉我吗? }}?
或者我应该在WebAppi项目中只使用一个DI?
答案 0 :(得分:15)
我发现设置Ninject模块的实用方法可以在下面找到。
DependencyResolution
DependencyResolution
和您的域项目NinjectWebCommon.cs
ServiceModule.cs
,RepositoryModule.cs
等。
创建您的Ninject module(s)。有关详细说明,请参阅我的answer。DependencyResolution
项目和域项目的引用。在WebAPI项目NinjectWebCommon.cs
中初始化/注册刚刚创建的模块:
private static void RegisterServices(IKernel kernel)
{
var modules = new List<INinjectModule>
{
new ServiceModule(),
new RepositoryModule()
};
kernel.Load(modules);
}
我还将尝试解决另一个与您的问题相关的松散问题。我认为您当前的分层设置需要稍微改变。
你的图层的基本问题和可能是我最大的问题是你混淆了,因此紧密结合了Domain和Repository,这显然是一个基础设施问题。
我建议将图层重新设计为:
不要忘记,您的域层不对基础架构详细信息(如存储库)有任何了解,否则您将把您的域与不需要的实现细节紧密结合。 / p>
编辑:根据评论,我发现您对于放置位置以及如何命名是obviously编程中最困难的事情之一有一些顾虑。
所以我清除这种困惑的想法是:
图层:是属于一起的类,方法等的逻辑分离或集合点。
每个图层可以包含多个项目或程序集。因此,如果要将项目分类为图层,可以在解决方案中创建名为图层的directories,并将各个项目放在这些目录中。这真的只是嘴里的味道问题,就像小费一样。
依赖性解析项目引用了任何所需的程序集(接口的域,其实现的服务/基础结构),并将它们连接起来供以后使用。
WebAPI项目只需要引用添加的域和依赖关系解析,这样你就可以在WebAPI方法/函数公共构造函数中询问你的接口,Ninject将在幕后为你做脏工作。
请不要忘记,这只是我的一个简单快速的脏架构建议,不知道您的确切要求和用例。
答案 1 :(得分:4)
如果我理解了您的问题,那么您在配置存储库层时遇到了麻烦,因为您的配置代码位于您的应用程序层中,该应用程序层可能只引用您的服务层(后者又引用您的存储库层)。我为解决这个问题所做的工作首先是在模块中创建配置(这些配置可以存在于任何层,但您必须参考Ninject)
对于您的回购图层:
public class RepoNinjectModule : NinjectModule
{
public override void Load()
{
Bind<IMyRepo>().To<MyRepo>();
}
}
在服务层中创建一个类似的模块:
public class ServiceNinjectModule : NinjectModule
{
public override void Load()
{
Bind<IMyService>().To<MyServce>();
}
}
然后,在您的应用程序层中,您可以动态加载模块(这是NinjectWebCommon.cs
的样子):
private static void RegisterServices(IKernel kernel)
{
kernel.Load(AppDomain.CurrentDomain.GetAssemblies());
}
有关模块的更多信息:https://github.com/ninject/Ninject/wiki/Modules-and-the-Kernel