2015-03-21 1 views
1

Все мои сервисы и их интерфейсы для домена находятся в пределах одного проекта, репозитория в другом. Я использую следующий код для регистрации сборки:Запуск виндзора регистрации регистрации и реализация только там, где реализация не является абстрактной или интерфейсом

public IWindsorContainer SetupWithWebRequest() 
{ 
    return Generate(c => c.LifestylePerWebRequest()); 
} 

public WindsorContainer SetupWithThread() 
{ 
    return Generate(c => c.LifestylePerThread()); 
} 

private WindsorContainer Generate(Action<ComponentRegistration> reg) 
{ 
    var container = new WindsorContainer(); 

    var types = new List<FromAssemblyDescriptor>(); 
    types.Add(Types.FromAssembly(typeof(BlogRepository).Assembly)); 
    types.Add(Types.FromAssembly(typeof(BlogEntryService).Assembly)); 

    foreach (var type in types) 
    { 
     container.Register(type.Pick().WithServiceAllInterfaces().Configure(reg)); 
    } 

    //ensure the db context is passed in. 
    container.Register(Component.For<IUserRepository<BlogUserEntity, int>>().LifeStyle.PerWebRequest.UsingFactoryMethod(() => new GenericUserRepository<BlogUserEntity, int>(new BlogEngineContext()))); 

    return container; 
} 

Приведенный выше код будет регистрировать много вещей, которые я не интересует о. Например, все, что IDisposable. Это, вероятно, не проблема, неудивительно, что это замедлит работу? Моя основная проблема заключается в том, что у меня есть один интерфейс, определенный на уровне домена, но он реализован на веб-сайте.

Код выше находится в области DLL и вызывается из веб-сайта (global.asax), как показано ниже:

var container = new WindsorContainerGeneration().SetupWithWebRequest(); 
container.RegisterControllers(Assembly.GetExecutingAssembly()); 

//setup the website to get its user from aspnet. 
container.Register(Component.For<IGetCurrentUserName>().LifeStyle.PerWebRequest.ImplementedBy(typeof(GetCurrentUserNameUsingAspnet))); 

GlobalConfiguration.Configuration.DependencyResolver = new WindsorDependencyResolver(container); 
ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container)); 

даже если я вручную зарегистрировать экземпляр IGetCurrentUserName контейнер будет уже зарегистрирован экземпляр где и сервис, и реализация являются интерфейсом.

Есть ли способ гарантировать, что только классы, реализующие интерфейс, будут зарегистрированы, а не выше?

ответ

1

Вы можете выбирать только классы, реализующие определенный интерфейс, используя types.BasedOn<IInterfaceName>()

Если вы хотите, чтобы отфильтровать только классы, реализующие любой интерфейс, который вы могли бы использовать это:

types.Where(type => type.GetInterfaces().Any() 
+0

работал отлично. Вчера я попробовал слишком сложную версию этого. должно быть, уже подумал об этом (или с понедельника пополудни). Спасибо – Jon

0

Вот пример осуществления:

protected virtual IEnumerable<IRegistration> GetComponentRegistrations() 
     { 
      return new IRegistration[] 
       { 
        Classes.FromAssembly(GetAssemblyNamed(MyAssembly)) 
          .BasedOn<IMyComponent>() 
          .If(x => x.IsContructable()) // this is it 
          .WithServiceDefaultInterfaces() 
       }; 
     } 

public static class TypeHelpers 
    { 
     public static bool IsContructable(this Type t) 
     { 
      return !t.IsAbstract && !t.ContainsGenericParameters; 
     } 
    } 

 Смежные вопросы

  • Нет связанных вопросов^_^