在哪里可以找到在多层应用程序Ninject模块 [英] Where to locate Ninject modules in a multi-tier application

查看:149
本文介绍了在哪里可以找到在多层应用程序Ninject模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序包括了一些后端组件(包括实体框架数据存储库层)是由一些前端组件(包括Windows服务和MVC3 Web应用程序)共享。

My application includes a number of back-end assemblies (including an Entity Framework data repository layer) that are shared by a number of front-end assemblies (including a Windows service and an MVC3 web application).

我的Ninject结合过程的理解是包含注射类型每个组件还应该包含一个Ninject模块,定义了这些类型的默认绑定。该组定义的模块的随后将被装入Ninject内核的消耗组件的

My understanding of the Ninject binding process is that each assembly that contains injectable types should also contain an Ninject module that defines the default bindings for these types. The set of defined modules would then be loaded into the Ninject Kernel of the consuming assemblies.

不过,我遇到了问题,因为所需的绑定范围并不总是一致的。例如,我的MVC项目需要绑定到数据上下文 InRequestScope ,而Windows服务结合到同一类 InThreadScope

However, I am running into problems, since the required binding scope is not always consistent. For example, my MVC project needs to bind to the data context InRequestScope, whereas the Windows service binds to the same class InThreadScope.

我可以明显由所有的模块重新定位到前端项目解决了这个问题,从而保持每个模块为每个使用场景的单独的副本,但这似乎哈克,因为它重复多跨多个项目的模块的内容。

I can obviously solve this problem by relocating all the modules into the front-end projects and thus maintain separate copies of each module for each usage scenario, but this seems hacky, since it duplicates much of the module content across multiple projects.

有没有什么地方模块应设在一个多层应用程序,我怎么能和我的需要调和这对项目之间的差异结合最佳实践?

Is there a best practice about where modules should be located in a multi-tier application and how can I reconcile this with my need for binding differences between projects?

非常感谢您的建议,

推荐答案

有关与单个应用的解决方案,一般的建议是在应用程序项目(您的Web应用程序或Web服务项目)注册您的容器。 Web应用程序这通常是在Global.asax 的Application_Start 。这其中,连线都在一起的地方被称为DI术语中成分根

For a solution with a single application, the general advice is to register your container in the application project (your web app, or web service project). For a web application this would typically be the Global.asax Application_Start. This place where you wire everything together is called the Composition Root in DI terminology.

通过多应用的解决方案,你仍然有每个应用程序项目的单一成分的根。这必须的,因为每个应用程序有其独特的结构。在另一方面,重复code总是不好的。你不希望有改变三个地方,当你引入一个新的抽象。

With a multi-application solution, you would still have a single composition root per application project. This has to be, since every application has its unique configuration. On the other hand, duplicated code is always bad. You don't want to have to change three places when you introduce a new abstraction.

诀窍是将所有注册下来的项目层次结构。例如,您可以定义一个引导程序集这就要看你的业务层组件(及以下),并让它对那些不改变组件全部注册。那么应用程序的组成根源可以使用该程序集获取默认的注册和使用应用程序扩展它特定的依赖关系。

The trick is to move all registrations down the project hierarchy. For instance you can define a single 'bootstrap assembly' that depends on your business layer assemblies (and below) and let it have all the registrations for those assemblies that don't change. The composition roots of the applications can then use that assembly to get the default registrations and extend it with the application specific dependencies.

这样的事情可能是这样的:

Such a thing might look like this:

// MVC Composition root
public static void Bootstrap()
{
    var container = new Container();

    // Default registrations
    BusinessLayerBootstrapper.Bootstrap(container);

    // Application specific registrations
    container.Bind<IUserContext>().To<AspNetUserContext>();

    DependencyResolver.Current = 
        new ContainerDependencyResolver(container);
}

// Windows Service Composition root
public static void Bootstrap()
{
    var container = new Container();

    // Default registrations
    BusinessLayerBootstrapper.Bootstrap(container);

    // Application specific registrations
    container.Bind<IUserContext>().To<SystemUserContext>()
        .SingleScoped();

    // Store somewhere.
    Bootstrapper.Container = container;
}

// In the BL bootstrap assembly
public static class BusinessLayerBootstrapper
{
    public static void Bootstrap(Container container)
    {
        container.Bind<IDepenency>().To<RealThing>();
        // etc
    }
}

虽然你不需要有一个单独的引导程序组件(你可以把这个code在BL本身),这可以让你保持你的业务层组件的任何依赖关系,您的容器免费的。

Although you don't need to have a separate bootstrapper assembly (you can place this code in the BL itself), this allows you to keep your business layer assemblies free from any dependencies to your container.

另外请注意,我打电话,而不是使用(Ninject)模块静态引导()方法。我试图让我的回答独立的框架,因为你的问题是一般性的建议将成为所有DI框架相同。但是,你当然可以,如果你想使用Ninject模块的功能。

Also note that I'm just calling a static Bootstrap() method, instead of using (Ninject) Modules. I tried to keep my answer independent of the framework, since your question is general and the advice will be the same for all DI frameworks. However, of course you can use the Ninject module feature if you want.

这篇关于在哪里可以找到在多层应用程序Ninject模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆