如何在ObjectMap的ObjectFactory.Initialize调用中使用命名实例?

时间:2011-06-25 04:54:39

标签: vb.net structuremap

我正在尝试进行以下引导:

            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 Logging.IErrorLogger

的名为“Disk”的实例

我理解为什么会发生这种情况..问题是,如何在注册表中使用命名实例?也许类似于SQLErrorLogger的ctor参数的延迟初始化?我不确定如何实现它。

提前感谢您提供的任何帮助。

2 个答案:

答案 0 :(得分:1)

我在StructureMap的最新版本(2.6.1)中找到了正确的方法:

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")

注意Ctor的Is方法,我们需要提供一个func(IContext),并使用IContext.ConstructedBy(Func())来调用ObjectFactory.Get ...以在这种情况下成功注册IErrorLogger。

据我所知,这是唯一可行的方法。其他Icontext方法(如IsThis和Instance)仅适用于已注册的类型。

答案 1 :(得分:0)

您的问题是您在配置之前尝试访问Container。为了使结构图在配置后评估对象分辨率,您需要为Is函数提供lambda。尝试解析已注册的类型时,将评估lambda。

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中的lambda语法,但我希望我做对了。

修改:

我在发布之前尝试过自己的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");