英文:
C# and .NET Core: The proper way to add an event handler to an object created by DI
问题
我正在使用.AddTransient
添加一个服务,以便在传递给任何构造函数时自动注入。当注入的对象被创建并传递给某个类的构造函数时,我需要添加一个事件处理程序。
我使用了以下代码:
builder.Services.AddTransient(factory =>
{
var rest = factory.GetService<RestUtilityService>();
rest.Exception += Api_Exception;
return rest;
})
但在调试时,该代码被多次调用,导致应用程序挂起。
您能告诉我如何在对象首次创建时添加事件处理程序吗?
当然,事件应该只被订阅一次,所以它应该在首次创建时完成。
谢谢
Jaime
英文:
I am adding a service using .AddTransient
to be injected automatically when it is passed to any constructor. I need to add an event handler when the injected object is created and passed to a constructor of some class.
I used this:
builder.Services
.AddTransient(factory =>
{
var rest = factory.GetService<RestUtilityService>();
rest.Exception += Api_Exception;
return rest;
})
But when debugging, that code is called several times and the application hangs.
Can you tell me how to add that event handler when the object is first created?
Of course, the event should be subscribed only once, so it should be done at first, and only, creation.
Thanks
Jaime
答案1
得分: 3
你的示例可能是无意中递归的,你应该明确地创建你的对象:
builder.Services
.AddTransient(factory =>
{
var rest = new RestUtilityService(factory.GetService<SomeDependency>());
rest.Exception += Api_Exception;
return rest;
})
这并不一定意味着这是解决问题的最佳方法。如果你想要集中处理异常,可能更好的方法是创建一个 IExceptionHandler
,将其声明为单例,并将其作为你的 RestUtilityService
的依赖项。
英文:
Your example is probably unintentionally recursive, you should probably create your object explicitly:
builder.Services
.AddTransient(factory =>
{
var rest = new RestUtilityService(factory.GetService<SomeDependency>());
rest.Exception += Api_Exception;
return rest;
})
That does not necessarily mean that this is the best approach to solve the problem. If you want some central handling of exceptions it might be better to create a IExceptionHandler
, declare an implementation of this as a singleton, and make this a dependency of your RestUtilityService
.
答案2
得分: 1
这段代码会导致堆栈溢出异常,因为注册部分在递归调用自身。
相反,您可以尝试以下方式之一:
builder.Services
.AddTransient(factory =>
{
var rest = new RestUtilityService();
rest.Exception += Api_Exception;
return rest;
})
或者:
builder.Services
.AddTransient(factory =>
{
var rest = ActivatorUtilities.Create<RestUtilityService>(factory);
rest.Exception += Api_Exception;
return rest;
})
英文:
This code will result in a stack overflow exception because the registration is recursively calling itself.
Instead, you might try something as follows:
builder.Services
.AddTransient(factory =>
{
var rest = new RestUtilityService();
rest.Exception += Api_Exception;
return rest;
})
or:
builder.Services
.AddTransient(factory =>
{
var rest = ActivatorUtilities.Create<RestUtilityService>(factory);
rest.Exception += Api_Exception;
return rest;
})
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论