Как использовать именованный экземпляр в вызове ObjectFactory.Initialize для StructureMap? - PullRequest
0 голосов
/ 25 июня 2011

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

            x.For(Of IErrorLogger).Use(Of ErrorLogger.SQLErrorLogger)().
                Ctor(Of IErrorLogger)("backupErrorLogger").Is(ObjectFactory.GetNamedInstance(Of IErrorLogger)("Disk"))

            x.For(Of IErrorLogger).Add(
                Function()
                    Return New ErrorLogger.DiskErrorLogger(
                        CreateErrorFileName(ServerMapPath(GetAppSetting("ErrorLogFolder"))))
                End Function).Named("Disk")

Но это показывает эту ошибку:

Код исключения StructureMap: 200 Не удалось найти экземпляр с именем «Диск» для ведения журнала PluginType .IErrorLogger

Я вроде понимаю, почему это происходит ... вопрос в том, как использовать именованный экземпляр в реестре? Может быть, что-то вроде ленивой инициализации аргумента ctor для SQLErrorLogger? Я не уверен, как это сделать.

Заранее благодарим за любую помощь, которую вы можете оказать.

Ответы [ 2 ]

1 голос
/ 27 июня 2011

Я нашел правильный способ сделать это в последней версии (2.6.1) StructureMap:

x.For(Of IErrorLogger).Use(Of ErrorLogger.SQLErrorLogger)().
    Ctor(Of IErrorLogger)("backupErrorLogger").Is(
        Function(c) c.ConstructedBy(Function() ObjectFactory.GetNamedInstance(Of IErrorLogger)("Disk"))
        )

x.For(Of IErrorLogger).Add(Function() _
        New ErrorLogger.DiskErrorLogger(
            CreateErrorFileName(ServerMapPath(GetAppSetting("ErrorLogFolder"))))
        ).Named("Disk")

Обратите внимание на метод Is Ctor, нам нужно предоставить функцию (IContext),и используйте IContext.ConstructedBy (Func ()) для вызова ObjectFactory.Get ... для успешной регистрации IErrorLogger в этом случае.

Это единственный способ сделать это, насколько я знаю.Другие методы Icontext, такие как IsThis и Instance, будут работать только с уже зарегистрированным типом.

0 голосов
/ 26 июня 2011

Ваша проблема в том, что вы пытаетесь получить доступ к контейнеру до его настройки. Чтобы заставить structmap оценить разрешение объекта после конфигурации, вам нужно указать лямбду для функции Is. Лямбда будет оцениваться при попытке разрешить зарегистрированный тип.

x.[For](Of ILogger)().Add(Of SqlLogger)().Ctor(Of ILogger)("backupErrorLogger")_
    .[Is](Function(context) context.GetInstance(Of ILogger)("Disk"))
x.[For](Of ILogger)().Add(Of DiskLogger)().Ctor(Of String)("errorFileName")_
    .[Is](CreateErrorFileName(ServerMapPath(GetAppSetting("ErrorLogFolder"))))_
    .Named("Disk")

Отказ от ответственности: я не совсем осведомлен о лямбда-синтаксисе в VB.NET, но надеюсь, что все правильно понял.

Редактировать:

Рабочая версия C #, которую я попробовал перед публикацией, была такой:

ObjectFactory.Initialize(i =>
            {
                i.For<ILogger>().Add<SqlLogger>()
                    .Ctor<ILogger>("backup").Is(
                        c => c.GetInstance<ILogger>("disk"))
                    .Named("sql");
                i.For<ILogger>().Add<DiskLogger>().Named("disk");
            });

var logger = ObjectFactory.GetNamedInstance<ILogger>("sql");
...