2014-11-28 3 views
1

На ContainerBuilder я могу сделать следующее:Регистрация делегата FUNC по соглашению

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, которые должны быть связаны таким «соглашением».

ответ

0

В конце концов мы решили использовать IRegistrationSource. Единственная альтернатива, которую я «нашел», заключалась бы в обнаружении всех типов отражения (не используя API autofac ...), а затем генерации делегата для каждого и регистрации этого с помощью 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; } 
    } 
}