Замок Виндзор с несколькими конструкторами - PullRequest
6 голосов
/ 17 ноября 2009

В настоящее время я перехожу к использованию 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, я говорю: есть идеи?

Ответы [ 2 ]

7 голосов
/ 17 ноября 2009

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

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

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

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

Давайте вернемся к тому, с чего начали?

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

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

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...
    // -----------------------------------------------
}

Пожалуйста, сообщите об этой проблеме в Список пользователей замка или прямо на трекер проблем , чтобы исправить это.

0 голосов
/ 23 ноября 2017

По состоянию на Виндзор 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

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