Почему я не могу зарегистрировать один класс для нескольких интерфейсов в Виндзоре? - PullRequest
4 голосов
/ 28 августа 2011

Я пытаюсь зарегистрировать все классы, которые реализуют мой IProcess<T1, T2> интерфейс, в Windsor.Для этого в моем инсталляторе есть следующий код:

        // Register all implemented process interfaces
        var procTypes = AppDomain.CurrentDomain
                                 .GetAssemblies()
                                 .SelectMany(x => x.GetTypes())
                                 .Where(x => x.IsDerivedFromOpenGenericType(typeof(IProcess<,>)))
                                 .ToList();

        foreach (var procType in procTypes)
            foreach (var procInterface in procType.GetInterfaces().Where(x => x.IsDerivedFromOpenGenericType(typeof(IProcess<,>))))
                container.Register(Component.For(procInterface).ImplementedBy(procType).LifeStyle.Transient);

Один из классов, которые я пытаюсь зарегистрировать, следующий:

public class PositionProcesses 
    : IProcess<CreatePositionParams, PositionDisplayViewModel>,
      IProcess<EditPositionParams, PositionDisplayViewModel>
{
}

Первый интерфейс регистрируется правильно,но после регистрации второго интерфейса, который будет реализован этим классом, я получаю следующую ошибку:

Test method MyJobLeads.Tests.Controllers.PositionControllerTests.Windsor_Can_Resolve_PositionController_Dependencies threw exception: 
Castle.MicroKernel.ComponentRegistrationException: There is a component already registered for the given key MyJobLeads.DomainModel.Processes.Positions.PositionProcesses

на первой итерации цикла мои переменные:

+       procInterface   {Name = "IProcess`2" FullName = "MyJobLeads.DomainModel.Data.IProcess`2[[MyJobLeads.DomainModel.ProcessParams.Positions.CreatePositionParams, MyJobLeads.DomainModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[MyJobLeads.DomainModel.ViewModels.Positions.PositionDisplayViewModel, MyJobLeads.DomainModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}   System.Type {System.RuntimeType}
+       procType    {Name = "PositionProcesses" FullName = "MyJobLeads.DomainModel.Processes.Positions.PositionProcesses"}  System.Type {System.RuntimeType}

на второй:

+       procInterface   {Name = "IProcess`2" FullName = "MyJobLeads.DomainModel.Data.IProcess`2[[MyJobLeads.DomainModel.ProcessParams.Positions.EditPositionParams, MyJobLeads.DomainModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[MyJobLeads.DomainModel.ViewModels.Positions.PositionDisplayViewModel, MyJobLeads.DomainModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"} System.Type {System.RuntimeType}
+       procType    {Name = "PositionProcesses" FullName = "MyJobLeads.DomainModel.Processes.Positions.PositionProcesses"}  System.Type {System.RuntimeType}

(оба из отладчика VS.

Есть идеи?

Ответы [ 2 ]

4 голосов
/ 28 августа 2011

Вы должны использовать условную регистрацию компонентов

BasedOnDescriptor processes = AllTypes.FromAssembly(assemblyWithProcesses)
    .BasedOn(typeof (IProcess<,>))
    .WithService.AllInterfaces()
    .Configure(x => x.LifeStyle.Transient);

container.Register(processes)

РЕДАКТИРОВАТЬ удален первый образец, как упомянуто @ Krzysztof-kozmic

2 голосов
/ 28 августа 2011

Если у вас есть один компонент, зарегистрированный для нескольких сервисов, я думаю, вам придется называть каждую регистрацию вручную.

См .: http://docs.castleproject.org/Windsor.Registering-components-by-conventions.ashx#Configuring_registration_13

container.Register(
    Component.For(procInterface)
             .ImplementedBy(procType)
             .LifeStyle.Transient
             .Named(component.Implementation.FullName
                 + "-"
                 + procInterface.Name)
    );

Это должно зарегистрировать каждыйкомпонент с полным именем типа плюс интерфейс, для которого вы его регистрируете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...