问题
Given the small example below, is there a way to mark (attribute, name convention,... ) the MyInterface
argument in MyService2
, so that it will resolve correctly, or is the only way to pass in MyInterface[]
?
I know that Castle Windsor can resolve it based on naming convention, but I haven't found something similar in DryIoc
public interface MyInterface { }
public class MyImplementationA : MyInterface { }
public class MyImplementationB : MyInterface { }
public class MyService1
{
public MyService1(MyInterface[] implementations) {
Console.WriteLine(implementations.GetType().Name);
}
}
public class MyService2
{
public MyService2(MyInterface implementationA) {
Console.WriteLine(implementationA.GetType().Name);
}
}
class Program
{
static void Main(string[] args)
{
var c = new Container();
c.Register<MyInterface, MyImplementationA>(serviceKey: "implementationA");
c.Register<MyInterface, MyImplementationB>(serviceKey: "implementationB");
c.Register<MyService1>();
c.Register<MyService2>();
var a = c.Resolve<MyService1>();
var b = c.Resolve<MyService2>();
}
}
回答1:
There are number of ways:
First by using service keys as in your comment
Here the consumer selects dependency based on key.
c.Register<MyService2>(made: Made.Of(() =>
new MyService2(Arg.Of<MyInterface>(ServiceKeys.ImplementationA))));
update: or in constructor agnostic way
c.Register<MyService2>(made:
Parameters.Of.Type<MyInterface>(ServiceKeys.ImplementationA));
Dependency condition
Dependency selects the consumer based on condition:
c.Register<MyInterface, MyImplementationA>(setup: Setup.With(
condition: request => request.Parent.ServiceType == typeof(MyService2)));
Dependency is reused in resolution scope of specific consumer
It won't be Transient anymore, but it may be OK depending on your setup.
c.Register<MyService2>(setup: Setup.With(openResolutionScope: true));
c.Register<MyInterface, MyImplementationA>(Reuse.InResolutionScopeOf<MyService2>());
回答2:
Your registration was ok
c.Register<MyInterface, MyImplementationA>(serviceKey: "implementationA");
c.Register<MyInterface, MyImplementationB>(serviceKey: "implementationB");
If you want to Resolve a concrete Instance for A or B, you can get it easier by this:
var a = c.Resolve<MyInterface>(serviceKey: "implementationA");
var b = c.Resolve<MyInterface>(serviceKey: "implementationB");
来源:https://stackoverflow.com/questions/34612600/resolve-one-of-multiple-registrations-with-dryioc