Стиль жизни в Виндзорском замке не регистрируется

1

Я использую структуру, которая позволяет мне перехватывать некоторые точки входа.
Рамка рамки не является веб-запросом, а не потоком, а не временным, что-то вроде потокового, но я видел много мест с повторным использованием потоков.
Поэтому мне нужна настраиваемая область, где я говорю, с чего начать и где заканчивать область.
Поскольку у меня много зависимостей, большинство из них определяются в статическом контракторе, потому что они не имеют гражданства.
У меня есть одна зависимость, которую на самом деле нужно вводить при каждом перехвате инфраструктуры.

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

public void Execute(AppContext context)
{

    using (var s = CastleContainer.Container.BeginScope())
    {
        CastleContainer.Container.Register(Component.For<AppContext>().LifestyleScoped().Instance(context));
        var logic = CastleContainer.Container.Resolve<ICustomerLogic>();
        // begin invocation
    }
}

ICustomerLogic имеет зависимость от ICustomreDal и ICustomreDal имеет зависимость в AppContext.

Поэтому, когда я разрешаю Resolve<ICustomerLogic>() я хочу быть уверенным, что ICustomreDal имеет текущий AppContext.

ICustomerLogic и зарегистрирован как singleton, а ICustomreDal зарегистрирован как переходный.

Первое исполнение работает нормально, второе исполнение я получаю:

Не удалось зарегистрировать AppContext. Уже есть компонент с этим именем. Вы хотите изменить существующий компонент? Если нет, убедитесь, что вы указали уникальное имя.

Разве замок не должен делать сегментацию области, поэтому каждая область имеет свои собственные зависимости?
Что я делаю не так?

Обратите внимание, что мы говорим о 50 казнях за секунду.

Теги:
scope
castle-windsor

1 ответ

1

BeginScope не относится к регистрации, это касается только разрешения компонентов. Он будет следить за тем, чтобы какой-либо компонент, созданный в используемом статусе, со статусом "Сфера охвата" был освобожден (если необходимо), когда заканчиваются операторы использования. Он не отменяет регистрацию компонентов, зарегистрированных в блоке. В общем, это плохая идея зарегистрировать свои компоненты в нескольких местах. Только регистрируйте компоненты при запуске приложения.

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

в вашем регистрационном коде используйте:

Component.For<ICustomerLogic>().ImplementedBy<CustomerLogic>().LifestyleScoped
Component.For<AppContext >().UsingFactoryMethod(() => (AppContext)Thread.GetNamedDataSlot("context")).LifestyleTransient() // or scoped

адаптируйте функцию Execute к:

public void Execute(AppContext context)
{
    using (var s = CastleContainer.Container.BeginScope())
    {
        Thread.SetData(Thread.GetNamedDataSlot("context"), context);
        var logic = CastleContainer.Container.Resolve<ICustomerLogic>();
        Thread.SetData(Thread.GetNamedDataSlot("context"), null);
        // begin invocation
    }
} 

Удачи,

Marwijn.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню