简单的注射器 - 我可以拦截创建对象吗
我知道我可以使用container.Options.RegisterResolveInterceptor
每次解析对象时都会收到通知,但对于我的场景,我只想在创建对象时才会收到通知。简单的注射器 - 我可以拦截创建对象吗
例如,如果类型注册为Lifestyle.Singleton
,我希望我的委托在解析类型时(在创建单例实例时)首次运行,但不在随后的调用中解析。
有没有简单的方法来做到这一点?
正如您已经发现的那样,RegisterResolveInterceptor
允许拦截直接从容器中解析出的类型。这意味着如果您致电GetInstance<ILogger>()
,则RegisterResolveInterceptor
允许缠绕,但它不会停止执行任何依赖关系。
要挂钩创建类型,您可以使用RegisterInitializer
重载之一。 RegisterInitializer
主要是为Simple Injector创建的类型添加一些额外的初始化,但还有其他有趣的用例。
如果你有你想收到通知的具体类型,则可以使用RegisterInitializer<T>(Action<T>)
超载,其中指定类型或抽象你有兴趣。比如:
container.RegisterInitializer<ILogger>(logger =>
{
System.Console.WriteLine(logger.ToString());
});
在这种情况下, ,初始化会上瘾到从分配任何注册,例如:
container.Register<ILogger>(() => new DbLogger());
container.Register<ILogger, FileLogger>();
container.Register<EventLogLogger>();
所有三种注册(假设EventLogLogger
工具)将获得丰富与初始化程序。
但是,如果没有特定的类型或抽象要插入,而是需要广泛的类型,或者需要了解有关类型的更多信息(例如其生活方式),则可以使用第二个RegisterInitializer
过载。这个重载需要一个将被执行的动作和一个谓词,它允许你指定动作将被提供给哪个注册。例如:
container.RegisterInitializer(
data => System.Console.WriteLine(data.Registration.ImplementationType.Name),
context => context.Registration.Lifestyle == Lifestyle.Singleton);
前面的代码段寄存器即会创建写入到控制台的类型的名称,在该注册是Singleton
情况下的初始值设定。你可以用Glimpse plugin for Simple Injector找到一个例子。 Glimpse插件uses这个RegisterInitializer
重载,因此它可以通知用户在特定请求期间创建哪些类型。
谢谢史蒂文! RegisterInitializer的第二重载正是我正在寻找的,因为我需要处理任何类型。这是我的一个跟踪对象的库(保留并应用它们的属性)。例如。窗口位置和大小,配置设置,上次输入的数据等等......通过与IOC集成,使用一行代码,我可以跟踪由容器创建的所有对象,这非常整洁! – anakic
我只是把它放在这里(https://github.com/anakic/Jot),以防你好奇地偷看:) – anakic