1

我使用该RegisterInitializer方法在基类型中注入属性,如下所示:

container.RegisterInitializer<BaseHandler>(handler =>
{
    handler.Context = container.GetInstance<HandlerContext>();
});

这很好用,但RegisterInitializer不会对从 BaseHandler 继承的所有注册类型触发。当我打电话给自己时,它似乎没有运行new

var url = ConfigurationManager.AppSettings["NotificationServiceUrl"];
container.Register<Handler<NotifyCustomerMessage>>(() => 
    new NotifyCustomerHandler(url));

// many other Handler<T> lines here

为什么会这样,我该如何解决?

4

1 回答 1

2

更新

此行为在Simple Injector 2中发生了变化:初始化程序现在也将在Func<T>注册时触发。原因是 Simple Injector 现在有明确的生活方式支持,现在实际上表现得像 StructureMap(如下所述)。


你的观察是正确的。Simple Injector 文档是这样描述的:

注意:容器将无法在使用new运算符手动构造的类型上调用初始化委托。尽可能使用自动构造函数注入。

克服这个问题的最好方法是允许 Simple Injector 使用自动构造函数注入。

NotifyCustomerHandler需要一个string构造函数参数,这使得无法进行自动构造函数注入。你NotifyCustomerHandler似乎有多重责任。通过将通知服务隐藏在INotificationService接口后面并让处理程序依赖于该接口,从处理程序功能中抽象出通知服务。您可以将该配置值注入到通知服务中。

关于 Simple Injector 以这种方式运行的一些背景信息

尽管其他 DI 框架(例如StructureMap及其OnCreationForAll方法)即使在您新建类型时也会调用委托,但 Simple Injector 不会。这是由于框架期望用户注册生活方式的差异造成的。

使用 StructureMap,生活方式是通过显式调用该LifecycleIs方法来配置的。使用 Simple Injector,用户应该通过注册自己实现生活方式的代表来配置生活方式。例如查看文档中的Per Thread 生活方式示例。使用 StructureMap 它是为您控制生命周期的框架,而使用 Simple Injector 它通常取决于用户。

换句话说,StructureMap 期望注册的委托总是创建一个新实例,而 Simple Injector 没有这种期望。因为 StructureMap 期望返回一个新实例,所以它可以在调用委托后安全地初始化该对象。实例的缓存在其他地方完成。然而,Simple Injector不会对从此类委托返回的对象调用初始化程序,因为这可能会一遍又一遍地重新初始化同一个对象,这可能会导致意外的应用程序行为和可能的性能问题。

我希望这有帮助。

于 2011-06-24T08:24:02.740 回答