使用泛型类型

时间:2017-10-20 04:20:00

标签: c# generics dependency-injection autofac

我需要这个IService可重用。每当IService注入构造函数时,我都需要Service.Dependent来引用注入类的类型。

builder.Register<Service>(c =>
        {
            var a = new Service();
            a.Dependent = c.Resolve<CallingType??>(TypedParameter.From(a));
            return a;
        }).As<IService>();

interface IService {}

class Service : IService {
    BaseClass Dependent {get; set;}
}


class SomeClass : BaseClass {
    SomeClass(IService service) {
        service.Dependent //This should be type BaseClass of SomeClass
    }
}

1 个答案:

答案 0 :(得分:2)

Autofac支持open generic registrationcircular dependencies 所以可以这样做:

builder.RegisterGeneric(typeof (Service<>))
    .As(typeof (IService<>))
    .InstancePerLifetimeScope()
    .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
builder.RegisterType<SomeClass>()
    .InstancePerLifetimeScope();

container.Resolve<IService<SomeClass>>()将返回您的注入SomeClass实例的服务,该实例将递归接收此Service实例。

似乎在注册期间没有提取被调用者类型的选项。 对于您的更新示例,自定义Registration Source可能会有所帮助 这是从BaseType类型继承的“通用”注册。 但它看起来像过度工程。

public class HandlerRegistrationSource : IRegistrationSource
{
  public IEnumerable<IComponentRegistration> RegistrationsFor(
    Service service,
    Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
  {
    var swt = service as IServiceWithType;
    if(swt == null || !typeof(BaseClass).IsAssignableFrom(swt.ServiceType))
    {
      // It's not a request for the BaseClass type, so skip it.
      return Enumerable.Empty<IComponentRegistration>();
    }        
    var registration = new ComponentRegistration(
      Guid.NewGuid(),
      new DelegateActivator(swt.ServiceType, (c, p) =>
        {
          var myService = c.Resolve<IService>();
          ...
        }
        ...
  }
  ...
}