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

后端 未结 3 2058
一整个雨季
一整个雨季 2020-12-08 10:32

I have an interface.

public interface ISomeInterface {...}

and two implementations (SomeImpl1 and SomeImpl2):

public class         


        
3条回答
  •  一整个雨季
    2020-12-08 10:45

    If you can switch from constructor injection to property injection, and let both services derive from the same base class (or implement the same interface), you can do the following:

    builder.RegisterType().OnActivating(e =>
    {
        var type = e.Instance.GetType();
    
        // get ISomeInterface based on instance type, i.e.:
        ISomeInterface dependency =
            e.Context.ResolveNamed(type.Name);
    
        e.Instance.SomeInterface = dependency;
    });
    

    For this to work you need to define the property on the base type (or interface). This solution is very flexible and would even allow you to complex things such as injecting a generic type, based on the parent type, as can be see below:

    builder.RegisterType().OnActivating(e =>
    {
        var type = 
           typeof(GenericImpl<>).MakeGenericType(e.Instance.GetType());
    
        e.Instance.SomeInterface = (ISomeInterface)e.Context.Resolve(type);
    });
    

    This approach has a few downsides:

    1. We need property injection.
    2. We need a base type or interface that contains that property.
    3. We need reflection to build the type, which might have an impact on performance (instead of the container building an efficient delegate) (although we might be able to speed things up by caching the type).

    On the upside, this design is simple and works for almost any container.

提交回复
热议问题