我正在尝试进行以下引导:
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参数的延迟初始化?我不确定如何实现它。
提前感谢您提供的任何帮助。
答案 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");