IoC在类库中。 在哪里引导
我正在使用可以被其他组件重用的类库。 在这个类库中,我使用unity来进行dependency injection。 对于这个类库,我创建了一个测试项目。 调用者也获得了一个测试项目。 我不确定的一件事是绑定的位置。 我应该将其合并到类库中,还是应该从调用应用程序中执行此操作?
这是一个有趣的问题。 如何dependency injection没有入口点的可重用组件。 我真的很想看到其他人的回答。
dependency injection是入口点组装的责任。 然而,如果你有很多需要DI的类和程序集,那么对于某些类/程序集来说它们可能是空闲的,而且任务变得繁重。
解决方案一
使用约定优于配置。 你坚持实现IFoo
等的Foo
类规则。许多DI框架都有使用约定来设置它的方法。
解决方案二
以上解决方案无法解决所有问题,因为有时您需要参数化注射设置。 这是我解决问题的方法(特别是对于那些由MEF加载的程序集,这是针对AutoFac
):
创建了一个接口IIocInstaller
,其中容器(或构建器通过)
public interface IIocInstaller { void Setup(ContainerBuilder builder); }
创建了一个标记需要DI的程序集的程序集属性:
[AttributeUsage(AttributeTargets.Assembly)] public class ExportAssemblyAttribute : Attribute { }
在每个程序集中,我创建了一个设置DI的类:
[assembly: ExportAssembly] namespace This.That { [Export(typeof(IIocInstaller))] public class IocInstaller : IIocInstaller { public void Setup(ContainerBuilder builder) { .... } } }
然后在入口点,我有一个公共代码,它查看具有assembly属性的所有已加载程序集(包括MEFed程序集),然后查找实现IIocInstaller
的类型,然后在它们上调用Setup。
我知道已经选择了一个答案,但我认为Unity的一部分被忽略了。 由于这是一个特定的Unity问题,我想我指出了实现IUnityContainerExtensionConfigurator的UnityContainerExtension基类。 这是为了扩展API库,使拥有Container的入口点应用程序能够轻松地确保您的库正确地注册到Container,并允许API所有者控制注册的内容和怎么样。
为此,Microsoft Enterprise Libraries使用它。
我将使用Logging库作为一个简单的:
public class LoggingUnityExtension : UnityContainerExtension { protected override void Initialize() { Container.RegisterType(new ContainerControlledLifetimeManager()); } }
然后入口点应用程序执行此操作:
public class Bootstrapper : UnityBootstrapper { protected override void ConfigureContainer() { base.ConfigureContainer(); Container.AddNewExtension(); Container.AddNewExtension(); // ... } // ... }
现在,他们已经注册了Enterprise Library和Logging库的API。 使用此方法的入口点应用程序非常简单,这是任何库开发人员应该具有的目标。
从调用应用程序执行此操作会给调用应用程序带来更多负担。 没有机会省略初始化并陷入困境。
我会在类库中执行它,例如在静态构造函数中。
确定创建名为Project.Ioc的库。 在这里安装Unity。 将其他图层引用到Ioc库。 和Ioc Library到表示层。 创建一个名为UnityHelper的类。
/// /// Bind the given interface in request scope /// public static class IocExtensions { public static void BindInRequestScope(this IUnityContainer container) where T2 : T1 { container.RegisterType(new HierarchicalLifetimeManager()); } public static void BindInSingletonScope(this IUnityContainer container) where T2 : T1 { container.RegisterType(new ContainerControlledLifetimeManager()); } } /// /// The injection for Unity /// public static class UnityHelper { public static IUnityContainer Start() { var container = BuildUnityContainer(); DependencyResolver.SetResolver(new Unity.Mvc4.UnityDependencyResolver(container)); return container; } /// /// Inject /// /// private static IUnityContainer BuildUnityContainer() { var container = new UnityContainer(); // register all your components with the container here // it is NOT necessary to register your controllers // Database context, one per request, ensure it is disposed container.BindInRequestScope(); container.BindInRequestScope(); //Bind the various domain model services and repositories that eg our controllers require container.BindInRequestScope(); container.BindInRequestScope(); //container.BindInRequestScope(); return container; } }
看看MvcForum项目。 有MvcForm.Ioc类库。 该库获取其他Layer引用。 只有一个名为UnityHelper的类。
https://github.com/leen3o/mvcforum
我希望这是你正在寻找的wat。