2016-11-05 76 views
1

我知道我可以使用container.Options.RegisterResolveInterceptor每次解析对象时都会收到通知,但对于我的场景,我只想在创建对象时才会收到通知。简单的注射器 - 我可以拦截创建对象吗

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

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

回答

1

正如您已经发现的那样,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重载,因此它可以通知用户在特定请求期间创建哪些类型。

+0

谢谢史蒂文! RegisterInitializer的第二重载正是我正在寻找的,因为我需要处理任何类型。这是我的一个跟踪对象的库(保留并应用它们的属性)。例如。窗口位置和大小,配置设置,上次输入的数据等等......通过与IOC集成,使用一行代码,我可以跟踪由容器创建的所有对象,这非常整洁! – anakic

+0

我只是把它放在这里(https://github.com/anakic/Jot),以防你好奇地偷看:) – anakic