Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
150 views
in Technique[技术] by (71.8m points)

c# - How to resolve interface based on service where it's passed to

I have an interface.

public interface ISomeInterface {...}

and two implementations (SomeImpl1 and SomeImpl2):

public class SomeImpl1 : ISomeInterface {...}
public class SomeImpl2 : ISomeInterface {...}

I also have two services where I inject ISomeInterface (via contructor):

public class Service1 : IService1 
{
   public Service1(ISomeInterface someInterface)
   {
   }
...
}

and

public class Service2 : IService2 
{
   public Service2(ISomeInterface someInterface)
   {
   }
...
}

I'm using Autofac as my IoC tool. The question. How can I configure Autofac registrations so SomeImpl1 will be automatically injected into Service1, and SomeImpl2 will be automatically injected into Service2.

Thank you!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Autofac supports identification of services by name. Using this, you can register your implementations with a name (using the Named extension method). You can then resolve them by name in the IServiceX registration delegates, using the ResolveNamed extension method. The following code demonstrates this.

var cb = new ContainerBuilder();
cb.Register(c => new SomeImpl1()).Named<ISomeInterface>("impl1");
cb.Register(c => new SomeImpl2()).Named<ISomeInterface>("impl2");
cb.Register(c => new Service1(c.ResolveNamed<ISomeInterface>("impl1"))).As<IService1>();
cb.Register(c => new Service2(c.ResolveNamed<ISomeInterface>("impl2"))).As<IService2>();
var container = cb.Build();

var s1 = container.Resolve<IService1>();//Contains impl1
var s2 = container.Resolve<IService2>();//Contains impl2

Alternative using RegisterType (as opposed to Register)

You can achieve the same result using the RegisterType extension method in combination with WithParameter and ResolvedParameter. This is useful if the constructor taking a named parameter also takes other non-named parameters that you don't care to specify in a registration delegate:

var cb = new ContainerBuilder();
cb.RegisterType<SomeImpl1>().Named<ISomeInterface>("impl1");
cb.RegisterType<SomeImpl2>().Named<ISomeInterface>("impl2");
cb.RegisterType<Service1>().As<IService1>().WithParameter(ResolvedParameter.ForNamed<ISomeInterface>("impl1"));
cb.RegisterType<Service2>().As<IService2>().WithParameter(ResolvedParameter.ForNamed<ISomeInterface>("impl2"));
var container = cb.Build();

var s1 = container.Resolve<IService1>();//Contains impl1
var s2 = container.Resolve<IService2>();//Contains impl2

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...