编程语言
首页 > 编程语言> > c#-基本的DI / IoC问题-体系结构,SimpleInjector

c#-基本的DI / IoC问题-体系结构,SimpleInjector

作者:互联网

关于以下类型的体系结构设置IoC容器时,我有一个简单的挂断.

在我的应用程序中,我有这样的图层(从下到上):

> Project.Domain
> Project.Web(System.Web.Http等,以及一些核心HTTP类型逻辑)

>在这个项目中有一个BaseController

>在Web API 2.2中实现GET / POST等的Project.MicroServices.这些继承自Project.Web中的BaseController,并引用Project.Domain
> Project.Logging,这是我尝试横切日志记录的尝试

当请求MicroServices层中的控制器(GET,POST等)时,SimpleInjector使用属性注入将ILogger的实例添加到BaseController.因此,MicroServices项目中的任何控制器都可以访问它.到目前为止,效果很好.

这是我的问题:

我想使日志记录即使在域层中也可以访问整个体系结构,而又不会违反任何交叉规则并保持解耦.我的想法也许是从日志记录层可以订阅的域层发布的事件.但是,我离题了.我不了解的是如何使SimpleInjector将Logger实例传递到域(如果需要,有想法吗?)是在应用启动时发生还是仅在Web请求上发生?应该是单例实例还是瞬态实例?以及如何与Log4Net最佳配合(我的体系结构可能过于复杂或不足).

我意识到注册是在启动时发生的,但是如何获取实例呢?据我了解,我应该使用自动构造函数注入,而不是使用Container.GetInstance()来获取实例,但是尽管我进行了广泛的阅读,但我仍然不太清楚在Web API请求和SimpleInjector的Web API之外如何工作扩展程序.

同样,有些无关.我正在抽象Log4Net功能,但是最近我了解到我可能不应该这样做.希望就此如何将所有这些联系在一起提出一些建议.

解决方法:

您的帖子有点含糊不清,充满了很多问题,没有更多的背景信息很难回答,但我会尽力而为.

I’d like to make logging accessible to the entire architecture, even
in the domain layer

如果您有清晰的日志抽象,则可以将该抽象提供给应用程序,并在整个应用程序中进行日志记录.

I am abstracting out the Log4Net functionality, but I recently learned
that I probably shouldn’t.

我不同意.我想你应该.尽可能避免使应用程序的核心依赖于第三方组件,并且使用日志记录确实很容易做到. define an abstraction很容易符合SOLID的原则.而且不要忘了,根据Dependency Inversion Principle,抽象应该是defined by the client.日志记录框架无法定义所需的抽象.

但是请确保不要陷入太多的日志陷阱,如here所述.在大多数情况下,您不应该经常进行日志记录,而应该很快失败,并拥有一些通用的代码段来为您完成日志记录,而不是遍历整个代码库的ILogger.Log调用.

而且,如果您要发布事件,由于事件是理想的日志记录系统,因此我认为这会大大减少您需要记录的时间.只需将这些事件附加到表或磁盘上,您就会知道在确切的时间发生了什么.几乎没有理由将更多信息写入日志.

What I don’t understand is how to make SimpleInjector pass the Logger
instance to the domain (if I should, thoughts?)

对此有很多意见.我和Mark Seemann支持anemic domain models with commands and events on top(或者我可以说我的命令和事件成为我的域模型吗?).其他人在其域对象中具有更多业务逻辑.这些对象需要某些服务,例如ILoanCalculator,并且您可能需要依赖项注入,因为让这些域对象通过Service Location请求服务是very bad idea.

但是不要忘记,构造函数注入还不止于此.对于您的域对象,可以使用方法注入,其中某些域方法需要的服务作为方法参数公开:

public class Loan
{
    public void PayLoan(LoanPeriod periodToPay, ILoanCalculator calculator)
    {
        // ...
    }
}

由于您将拥有调用这些域方法的服务类(我能说command handlers吗?),因此您可以在这些服务类上应用构造函数注入,并将依赖项传递给域方法.

I realize that registration happens on startup, but what about getting
instances?

在每个请求开始时检索实例(建立对象图).

From what I understand, I should use automatic constructor injection
and not use Container.GetInstance() to get instances

那是对的.尽可能在容器中解析的任何服务上使用构造函数注入.

but despite my extensive reading, I still can’t quite figure out how
that works outside of a Web API request and SimpleInjector’s Web API
Extensions.

我不确定我是否理解这一点.几乎任何应用程序都是基于请求的,无论它是Web应用程序,Windows服务还是命令行工具.使用Web应用程序,请求作为Web请求从Internet传入.使用Windows服务,您有一个定期关闭的计时器,每个脉冲都可以视为一个新请求(或者您正在使用SqlDependency,在这种情况下,引发事件是新请求的开始).控制台应用程序可能只会有一个请求,并在此后不久终止.对于Web应用程序,Simple Injector将隐式控制某些服务的生命周期,而Windows服务和后台进程则必须显式控制它.使用Simple Injector,可以使用LifetimeScopeExecutionContextScope生活方式来定义一个明确的范围,该范围控制此类请求的对象的生存期.实际上,WebApiRequestLifestyle在后台使用ExecutionContextScopeLifestyle并根据Web API请求开始和结束作用域.

标签:asp-net-web-api,dependency-injection,c,net,simple-injector
来源: https://codeday.me/bug/20191029/1958883.html