简单的注入器-我可以拦截对象的创建

本文关键字:对象 创建 我可以 注入器 简单 | 更新日期: 2023-09-27 18:16:41

我知道我可以使用container.Options.RegisterResolveInterceptor在每次解析对象时获得通知,但对于我的场景,我希望仅在创建对象时获得通知。

例如,如果类型注册为Lifestyle.Singleton,我希望我的委托在类型第一次解析时运行(当创建单例实例时),而不是在随后的解析调用中运行。

是否有简单的方法来做到这一点?

简单的注入器-我可以拦截对象的创建

正如您已经发现的,RegisterResolveInterceptor允许拦截直接从容器解析的类型。这意味着如果你调用GetInstance<ILogger>(), RegisterResolveInterceptor可以被包裹在ILogger周围,但是它不会离开它的任何依赖项。

要钩住类型的创建,可以使用RegisterInitializer重载之一。RegisterInitializer主要是为简单注入器创建的类型添加一些额外的初始化,但它还有其他有趣的用例。

如果你有一个特定的类型,你想要得到通知,你可以使用RegisterInitializer<T>(Action<T>)重载,在那里你指定你感兴趣的类型或抽象。例如:

container.RegisterInitializer<ILogger>(logger =>
{
    System.Console.WriteLine(logger.ToString());
});

在这种情况下,初始化器将被挂钩到任何可从ILogger分配的注册,例如:

container.Register<ILogger>(() => new DbLogger());
container.Register<ILogger, FileLogger>();
container.Register<EventLogLogger>();

所有三个注册(假设EventLogLogger实现了ILogger)都将通过初始化器得到充实。

但是,如果没有一个特定的类型或抽象,你想要挂钩,而是一个广泛的类型,或者你需要更多的信息的类型(如它的生活方式),你可以使用第二个RegisterInitializer重载。此重载接受一个将要执行的操作和一个谓词,该谓词允许您指定将该操作提供给哪些注册。例如:

container.RegisterInitializer(
    data => System.Console.WriteLine(data.Registration.ImplementationType.Name),
    context => context.Registration.Lifestyle == Lifestyle.Singleton);

前面的代码片段注册了一个初始化项,如果注册是Singleton,则该初始化项将把创建的类型的名称写入控制台。你可以在Simple Injector的Glimpse插件中找到一个例子。瞥见插件使用这个RegisterInitializer重载,所以它可以告诉用户在特定的请求期间创建了哪些类型。