在ContainerBuilder
我可以执行以下操作:
builder.Register<ScenariosConfig>(c =>
(ScenariosConfig)c.Resolve<ConfigFactory>()
.Create(typeof(ScenariosConfig)))
.SingleInstance();
使用装配扫描我可以执行以下操作:
builder.RegisterAssemblyTypes(assemblies)
.Where(HasSingletonAttribute)
.As(t => GetNameMatchingInterfaces(t))
.SingleInstance();
现在问题:有什么办法可以实现以下目标:?
builder.RegisterAssemblyTypes(assemblies)
.Where(... some condition)
.CreateByDelegate((container, type)
=> c.Resolve<ConfigFactory>().Create(type))
.SingleInstance();
我已经发现IRegistrationSource
可以实现类似的。{但是,对于我需要代表创建的每个约定IRegistrationSource
创建吨的性能影响,我有点怀疑......
而且,当你需要解决IRegistrationSource
的所有IFoo
实例时,{{1}}无法使用{{1}},而这些实例应受到这样一个&#34;约定的约束。
答案 0 :(得分:0)
最后我们选择使用IRegistrationSource
。我发现的唯一替代方法是检测每次反射的所有类型(不使用autofac API ...),然后为每个类型生成一个委托并使用autofac注册它。真的不会导致代码容易理解......
因此,为了完整起见,这里是IRegistrationSource
实现:
public class ConfigConventionRegistrationSource : IRegistrationSource
{
public IEnumerable<IComponentRegistration> RegistrationsFor(
Service service,
Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
var s = service as IServiceWithType;
if (s != null
&& s.ServiceType.IsClass
&& s.ServiceType.Name.EndsWith("Config")
&& !s.ServiceType.GetInterfaces().Any())
{
yield return RegistrationBuilder
.ForDelegate((componentContext, parameters) =>
CreateConfigByFactory(componentContext, s.ServiceType))
.As(s.ServiceType)
.SingleInstance()
.CreateRegistration();
}
}
private static object CreateConfigByFactory(
IComponentContext componentContext,
Type configType)
{
IConfig configFactory = componentContext.Resolve<IConfig>();
MethodInfo method = Reflector<IConfig>
.GetMethod(x => x.Load<object>())
.GetGenericMethodDefinition()
.MakeGenericMethod(configType);
try
{
return method.Invoke(configFactory, new object[0]);
}
catch (TargetInvocationException tex)
{
ExceptionDispatchInfo
.Capture(tex.InnerException)
.Throw();
throw; // will not be reached as thrown above ;-)
}
}
public bool IsAdapterForIndividualComponents
{
get { return false; }
}
}