2009-11-17 4 views
6

Долгосрочный читатель впервые писатель здесь. В настоящее время я перехожу к использованию Ninject для текущей версии Castle Windsor для простого приложения C# .NET.Замок Виндзор: проблема с несколькими конструкторами

По большей части конверсия прошла успешно, а реализация контейнеров выполнена безупречно. Однако у меня есть небольшая проблема с моими объектами репозитория.

У меня есть объект хранилища пользователя, который кодируется следующим образом:

public class UserRepository : IUserRepository { 
    public UserRepository(IObjectContext objectContext) { 
     // Check that the supplied arguments are valid. 
     Validate.Arguments.IsNotNull(objectContext, "objectContext"); 

     // Initialize the local fields. 
     ObjectContext = objectContext; 
    } 

    public UserRepository(IObjectContextFactory factory) 
     : this(factory.CreateObjectContext()) { 
    } 

    // ----------------------------------------------- 
    // Insert methods and properties... 
    // ----------------------------------------------- 
} 

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

<castle> 
    <components> 
     <component id="objectContextFactory" lifestyle="custom" 
        customLifestyleType="Common.Infrastructure.PerWebRequestLifestyleManager, Common.Castle" 
        service="Project.DAL.Context.IObjectContextFactory, Project.DAL.LINQ" 
        type="project.DAL.Context.ObjectContextFactory, Project.DAL.LINQ"> 
     </component> 
     <component id="userRepository" lifestyle="custom" 
        customLifestyleType="Common.Infrastructure.PerWebRequestLifestyleManager, Common.Castle" 
        service="Project.BL.Repository.IUserRepository, Project.BL" 
        type="Project.BL.Repository.UserRepository, Project.BL.LINQ"> 
      <parameters> 
       <factory>${objectContextFactory}</factory> 
      </parameters> 
     </component> 
    </components> 
</castle> 

Для меня все выглядит так, как должно. Когда я пытаюсь разрешить экземпляр службы IObjectContextFactory, я извлекаю объект ObjectContextFactory. Моя проблема возникает, когда я пытаюсь разрешить экземпляр службы IUserRepository. Я отношусь к следующему восхитительному исключению:

Невозможно создать компонент userRepository, так как он будет иметь удовлетворяющие зависимости. userRepository ждет следующих зависимостей:

Услуги:

- SandCastle.DAL.Context.IObjectContext which was not registered.

Я пробовал все, что я могу думать об этом. Итак, для вас, читателей stackoverflow, я говорю: есть идеи?

ответ

7

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

Windsor пытается сопоставить самый жадный конструктор (один с большинством параметров), который он может удовлетворить.

Однако в вашем случае есть два конструктора, которые имеют наибольшее количество параметров (одного), поэтому Windsor просто выбирает первый, где то, что означает «первый», не определено.

Действительно, если вы измените порядок своих конструкторов в исходном коде, ваш код начнет работать, хотя это взломать, полагаясь на недокументированное поведение и не делать этого.

Вернемся к тому, с чего мы начали?

Я сказал, что Виндзор смущен, потому что нет single Самый жалкий конструктор, который он может удовлетворить.

Быстро и четко определенные исправления можно было бы добавить поддельный параметр к одному из я конструкторов, так что они имеют разное количество параметров:

public class UserRepository : IUserRepository { 
    public UserRepository(IObjectContext objectContext, object fakeIgnoreMe) { 
     // Check that the supplied arguments are valid. 
     Validate.Arguments.IsNotNull(objectContext, "objectContext"); 
     // ignoring fake additional argument 
     // Initialize the local fields. 
     ObjectContext = objectContext; 
    } 

    public UserRepository(IObjectContextFactory factory) 
     : this(factory.CreateObjectContext()) { 
    } 

    // ----------------------------------------------- 
    // Insert methods and properties... 
    // ----------------------------------------------- 
} 

Пожалуйста, сообщите об этой проблеме, чтобы Castle users list или straight to issue tracker так, что он будет исправить.

+0

Работал как вполне достойно! Благодаря! – highvoltage

+2

«Windsor пытается соответствовать самому жадному конструктору (один с большинством параметров, которые он может удовлетворить)». Я думаю, что правильнее сказать «из списка конструкторов, которые содержат только разрешимые параметры, выбирается конструктор с наибольшим количеством параметров». – Steven

+0

@Steven как насчет сейчас? –

0

От Windsor 3.2.x

Если к конструктору применяется атрибут Castle.Core.DoNotSelectAttribute, он не будет выбран, независимо от других критериев.

public class UserRepository : IUserRepository 
{ 
    [DoNotSelect] // This constructor will be ignored by Windsor 
    public UserRepository(IObjectContext objectContext) 
    { 
     // ... 
    } 

    public UserRepository(IObjectContextFactory factory) 
     : this(factory.CreateObjectContext()) {} 
} 

Ссылка: https://github.com/castleproject/Windsor/blob/86696989a7698c45b992eb6e7a67b765b48108b0/docs/how-constructor-is-selected.md

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