您不需要实例来在 Autofac 中注册您的类型。如果您需要来自您的类型的信息,最好使用元信息,例如Attribute
. 类似的东西:
[FooMetadata("Foo1")]
public class Foo1 : IFoo
{ }
然后在注册时使用此元数据
builder.RegisterAssemblyTypes(assembly)
.AssignableTo<IFoo>()
.Named<IFoo>(t => t.GetCustomAttribute<FooMetadata>().Foo);
如果您需要在您的实例中获取命名类型,您可以使用IRegistrationSource
public class NamedFooRegistrationSource : IRegistrationSource
{
public bool IsAdapterForIndividualComponents => false;
public IEnumerable<IComponentRegistration> RegistrationsFor(
Service service,
Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
KeyedService keyedService = service as KeyedService;
if (keyedService == null || keyedService.ServiceKey.GetType() != typeof(String))
{
yield break;
}
IComponentRegistration registration = RegistrationBuilder
.ForDelegate(keyedService.ServiceType, (c, p) =>
{
Type foosType = typeof(IEnumerable<>).MakeGenericType(keyedService.ServiceType);
IEnumerable<IFoo> foos = (IEnumerable<IFoo>)c.Resolve(foosType);
foos = foos.Where(f => f.AutoFactName == (String)keyedService.ServiceKey).ToArray();
if (foos.Count() == 0)
{
throw new Exception($"no Foo available for {keyedService.ServiceKey}");
}
else if (foos.Count() > 1)
{
throw new Exception($"more than 1 Foo available for {keyedService.ServiceKey}");
}
else
{
return foos.First();
}
})
.Named((String)keyedService.ServiceKey, keyedService.ServiceType)
.CreateRegistration();
yield return registration;
}
}
然后Foo
以这种方式注册您的:
builder.RegisterAssemblyTypes(assembly)
.AssignableTo<IFoo>()
.As<IFoo>();
builder.RegisterSource<NamedFooRegistrationSource>();