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

时间:2016-11-05 14:02:36

标签: c# dependency-injection simple-injector

我知道我可以使用container.Options.RegisterResolveInterceptor在每次解析对象时收到通知,但对于我的场景,我只想在创建对象时收到通知。

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

有一种简单的方法吗?

1 个答案:

答案 0 :(得分:1)

正如您已经发现的那样,RegisterResolveInterceptor允许拦截直接从容器中解析的类型。这意味着如果您致电GetInstance<ILogger>()RegisterResolveInterceptor允许包围ILogger,但它不会关闭任何依赖项。

要挂钩创建类型,您可以使用其中一个RegisterInitializer重载。 RegisterInitializer主要是为Simple Injector创建的类型添加一些额外的初始化,但还有其他有趣的用例。

如果您想要获得特定类型的通知,可以使用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,它将把创建的类型的名称写入控制台。您可以在Glimpse plugin for Simple Injector中找到可以执行此操作的示例。 Glimpse插件usesRegisterInitializer重载,因此它可以通知用户在特定请求期间创建了哪些类型。