我有2只依赖服务:存储库和网关(SMS)。
我需要解决2级不同的版本,只有传递给网关的一个参数不同的服务。
该代码被简化为如下
public interface IService
{
string DoSomething();
}
public interface IServiceFoo
{
string DoSomething();
}
public interface IServiceBar
{
string DoSomething();
}
public interface IRepository { }
public class Repository : IRepository { }
public interface IGateway
{
string Name { get; set; }
}
public class Gateway : IGateway
{
public string Name { get; set; }
public Gateway(string name)
{
this.Name = name;
}
}
public class Service : IService, IServiceFoo, IServiceBar
{
private readonly IGateway _gateway;
private readonly IRepository _repo;
public Service(IRepository repo, IGateway gateway)
{
_gateway = gateway;
_repo = repo;
}
public string DoSomething()
{
return _gateway.Name;
}
}
失败的测试
[TestClass]
public class UnityTest
{
[TestMethod]
public void TestMethod1()
{
var container = new UnityContainer();
container
.RegisterType<IRepository, Repository>()
.RegisterType<IGateway, Gateway>("FooGateway", new InjectionConstructor("I am foo"))
.RegisterType<IGateway, Gateway>("BarGateway", new InjectionConstructor("I am bar"))
.RegisterType<IServiceFoo, Service>(new InjectionConstructor(new ResolvedParameter<IRepository>(), new ResolvedParameter<IGateway>("FooGateway")))
.RegisterType<IServiceBar, Service>(new InjectionConstructor(new ResolvedParameter<IRepository>(), new ResolvedParameter<IGateway>("BarGateway")));
var barGateway = container.Resolve<IGateway>("BarGateway");
var fooGateway = container.Resolve<IGateway>("FooGateway");
var serviceBar = container.Resolve<IServiceBar>();
var serviceBarGatewayName = serviceBar.DoSomething();
var serviceFoo = container.Resolve<IServiceFoo>();
var serviceFooGatewayName = serviceFoo.DoSomething();
Assert.AreEqual("I am bar", barGateway.Name); // pass
Assert.AreEqual("I am foo", fooGateway.Name); // pass
Assert.AreEqual("I am bar", serviceBarGatewayName); // pass
Assert.AreEqual("I am foo", serviceFooGatewayName); // FAIL
错误的网关被传递时,该服务是解决了,但是如果我的名字明确解决的网关,它出来正确的。 我想我失去了一些东西基本在ResolvedParameter(字符串名称)是如何工作的,但我认为它会在与该名称的容器类型。
仍然不知道为什么你的版本不工作,但这样做的工作(如我预期的):
var container = new UnityContainer();
container
.RegisterType<IRepository, Repository>()
.RegisterType<IGateway, Gateway>( "FooGateway", new InjectionConstructor( "I am foo" ) )
.RegisterType<IGateway, Gateway>( "BarGateway", new InjectionConstructor( "I am bar" ) )
//.RegisterType<IServiceFoo, Service>( new InjectionConstructor( new ResolvedParameter<IRepository>(), new ResolvedParameter<IGateway>( "FooGateway" ) ) )
//.RegisterType<IServiceBar, Service>( new InjectionConstructor( new ResolvedParameter<IRepository>(), new ResolvedParameter<IGateway>( "BarGateway" ) ) );
.RegisterType<IServiceFoo>( new InjectionFactory( c => new Service( c.Resolve<IRepository>(), c.Resolve<IGateway>( "FooGateway" ) ) ) )
.RegisterType<IServiceBar>( new InjectionFactory( c => new Service( c.Resolve<IRepository>(), c.Resolve<IGateway>( "BarGateway" ) ) ) );
请注意,我用InjectionFactory
代替InjectionConstructor
。
另一个版本的作品。 这一次,我把注册服务的你的方式,但我让他们命名和名称解析:
var container = new UnityContainer();
container
.RegisterType<IRepository, Repository>()
.RegisterType<IGateway, Gateway>( "FooGateway", new InjectionConstructor( "I am foo" ) )
.RegisterType<IGateway, Gateway>( "BarGateway", new InjectionConstructor( "I am bar" ) )
.RegisterType<IServiceFoo, Service>( "sf", new InjectionConstructor( new ResolvedParameter<IRepository>(), new ResolvedParameter<IGateway>( "FooGateway" ) ) )
.RegisterType<IServiceBar, Service>( "sb", new InjectionConstructor( new ResolvedParameter<IRepository>(), new ResolvedParameter<IGateway>( "BarGateway" ) ) );
//.RegisterType<IServiceFoo>( new InjectionFactory( c => new Service( c.Resolve<IRepository>(), c.Resolve<IGateway>( "FooGateway" ) ) ) )
//.RegisterType<IServiceBar>( new InjectionFactory( c => new Service( c.Resolve<IRepository>(), c.Resolve<IGateway>( "BarGateway" ) ) ) );
var barGateway = container.Resolve<IGateway>( "BarGateway" );
var fooGateway = container.Resolve<IGateway>( "FooGateway" );
var serviceBar = container.Resolve<IServiceBar>( "sb" );
var serviceBarGatewayName = serviceBar.DoSomething();
var serviceFoo = container.Resolve<IServiceFoo>( "sf" );
var serviceFooGatewayName = serviceFoo.DoSomething();
它也可以如下使用ParameterOverride完成
container
.RegisterType<IRepository, Repository>()
.RegisterType<IGateway, Gateway>("FooGateway", new InjectionConstructor("I am foo"))
.RegisterType<IGateway, Gateway>("BarGateway", new InjectionConstructor("I am bar"))
.RegisterType<IServiceFoo, Service>(new InjectionConstructor(new ResolvedParameter<IRepository>(), typeof(IGateway)))
.RegisterType<IServiceBar, Service>(new InjectionConstructor(new ResolvedParameter<IRepository>(), typeof(IGateway)));
var barGateway = container.Resolve<IGateway>("BarGateway");
var fooGateway = container.Resolve<IGateway>("FooGateway");
var serviceBar = container.Resolve<IServiceBar>(new ParameterOverride("gateway", barGateway));
var serviceBarGatewayName = serviceBar.DoSomething();
var serviceFoo = container.Resolve<IServiceBar>(new ParameterOverride("gateway", fooGateway));
var serviceFooGatewayName = serviceFoo.DoSomething();
Assert.AreEqual("I am bar", barGateway.Name); // pass
Assert.AreEqual("I am foo", fooGateway.Name); // pass
Assert.AreEqual("I am bar", serviceBarGatewayName); // pass
Assert.AreEqual("I am foo", serviceFooGatewayName); // pass