我有一个接口:IFoo
两个实现该接口的类:FooOne
和FooTwo
两个类ClassOne
并在构造函数中ClassTwo
接收一个IFoo
参数。
我如何配置统一以便ClassOne
接收一个FooOne
实例并仅使用一个容器ClassTwo
接收一个?FooTwo
我不能在运行时这样做,所以它必须在配置文件中。
我有一个接口:IFoo
两个实现该接口的类:FooOne
和FooTwo
两个类ClassOne
并在构造函数中ClassTwo
接收一个IFoo
参数。
我如何配置统一以便ClassOne
接收一个FooOne
实例并仅使用一个容器ClassTwo
接收一个?FooTwo
我不能在运行时这样做,所以它必须在配置文件中。
查看Unity 文档。
要获得更易读的配置文件,您应该为、 、 和IFoo
定义FooOne
类型FooTwo
别名。然后你需要注册映射到你的实现。您需要为映射设置一个。对于您的消费者,您需要注册一个.ClassOne
ClassTwo
IFoo
name
IFoo
InjectionConstructor
您的配置将如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="IFoo" type="UnityConfigFile.IFoo, UnityConfigFile" />
<alias alias="FooOne" type="UnityConfigFile.FooOne, UnityConfigFile" />
<alias alias="FooTwo" type="UnityConfigFile.FooTwo, UnityConfigFile" />
<alias alias="ClassOne" type="UnityConfigFile.ClassOne, UnityConfigFile" />
<alias alias="ClassTwo" type="UnityConfigFile.ClassTwo, UnityConfigFile" />
<container>
<register type="IFoo" name="1" mapTo="FooOne" />
<register type="IFoo" name="2" mapTo="FooTwo" />
<register type="ClassOne" mapTo="ClassOne">
<constructor>
<param name="foo">
<dependency type="IFoo" name="1" />
</param>
</constructor>
</register>
<register type="ClassTwo" mapTo="ClassTwo">
<constructor>
<param name="foo">
<dependency type="IFoo" name="2" />
</param>
</constructor>
</register>
</container>
</unity>
</configuration>
这是显示它如何工作的相应测试。
UnityConfigurationSection config =
(UnityConfigurationSection) ConfigurationManager.GetSection("unity");
IUnityContainer container = new UnityContainer();
container.LoadConfiguration(config);
ClassTwo two = container.Resolve<ClassTwo>();
Assert.IsInstanceOfType(two.Foo, typeof(FooTwo));
更新
在运行时你可以这样做
IUnityContainer container = new UnityContainer();
container.RegisterType<IFoo, FooOne>("One");
container.RegisterType<IFoo, FooTwo>("Two");
container.RegisterType<ClassOne>(new InjectionConstructor(
new ResolvedParameter<IFoo>("One")));
container.RegisterType<ClassTwo>(new InjectionConstructor(
new ResolvedParameter<IFoo>("Two")));
您需要为他们提供注册名称才能执行此操作:
// Create an instance of a service you want to use. Alternatively, this
// may have been created by another process and passed to your application
LoggingService myLoggingService = new LoggingService();
// Register the existing object instance with the container
container.RegisterInstance<IMyService>("Logging", myLoggingService);
// Register a mapping for another service your application will use
container.RegisterType<IMyService, myDataService>("DataService");
// When required, retrieve an instance of these services
IMyService theDataService = container.Resolve<IMyService>("DataService");
IMyService theLoggingService = container.Resolve<IMyService>("Logging");
我像这样在我的应用程序中设置
已安装 Nuget 包 Unity 版本 4.0.1
<package id="Unity" version="4.0.1" targetFramework="net452" />
在我的 App.config
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity>
<container>
<register type="MyApp.MainWindow, MyApp">
<lifetime type="singleton" />
</register>
<register name="UnityResolver" type="MyApp.Core.Interface.IResolver, MyApp.Core.Interface" mapTo="Avelyn.Core.Container.UnityResolver, Avelyn.Core" />
<register name="NinjectResolver" type="MyApp.Core.Interface.IResolver, MyApp.Core.Interface" mapTo="Avelyn.Core.Container.NinjectResolver, Avelyn.Core" />
</container>
</unity>
在我的 App.xaml.cs 中
var _container = new UnityContainer();
_container.LoadConfiguration();
IResolver _unityResolver = _container.Resolve<IResolver>("UnityResolver");
IResolver _ninject = _container.Resolve<IResolver>("NinjectResolver");
MainWindow _win = _container.Resolve<MainWindow>();