Design patterns 在通用存储库上使用Decorator模式实现AOP

Design patterns 在通用存储库上使用Decorator模式实现AOP,design-patterns,aop,decorator,simple-injector,repository-design,Design Patterns,Aop,Decorator,Simple Injector,Repository Design,我正在尝试构建一个原型,使用装饰器将面向方面编程应用到我的项目中。我的项目的某些部分将使用通用存储库(用于简单的CRUD),但最终我还将合并命令和查询处理程序(它们将执行特定任务,如ProcessCustomerOrder等)。另外,我想在这里举例说明的交叉关注点是安全性和日志记录 另外,我知道我的示例代码不是使用Decorator模式的代码,而是我为这个原型提供上下文的代码的一个示例 我知道还有其他实现AOP(或横切关注点)的方法,比如代理或代码编织模式,但我不熟悉这些模式,因此不知道它们之间

我正在尝试构建一个原型,使用装饰器将面向方面编程应用到我的项目中。我的项目的某些部分将使用通用存储库(用于简单的CRUD),但最终我还将合并命令和查询处理程序(它们将执行特定任务,如ProcessCustomerOrder等)。另外,我想在这里举例说明的交叉关注点是安全性和日志记录

另外,我知道我的示例代码不是使用Decorator模式的代码,而是我为这个原型提供上下文的代码的一个示例

我知道还有其他实现AOP(或横切关注点)的方法,比如代理或代码编织模式,但我不熟悉这些模式,因此不知道它们之间的权衡

我在这里使用一个控制台应用程序,只是为了展示如果我以链接方式“新建”它们,它们会是什么样子

我的问题是:

(1) 如何使用Simple Injector(在引导类中)将其连接起来,并且仍然保持相同的顺序

(2) 这是装饰器模式的正确用法吗(因为我没有使用基抽象、接口类或装饰器基)

(3) 是否有一种干净的方法可以在同一存储库中使用ILogger服务的多个实现(例如DatabaseLogger和ConsoleLogger),而无需注入两个不同的版本

(4) 实际的日志记录是在Repository方法中实现的,ILogger服务被注入Repository类中,但是有没有比硬连接记录器并仍然使用通用存储库更好的方法呢

(5) 根据我在这个原型中使用存储库的方式,我应该使用代理模式还是代码编织模式

此外,欢迎对该设计提出一般性评论

原型代码:

公共类程序
{
公共静态void Main(字符串[]args)
{
var e=新实体
{
Id=1,
Name=“示例实体”,
Description=“由装饰师使用”,
RowGuild=Guid.NewGuid()
};
控制器=
新控制器(
新通用存储(
新建ClientManagementContext(),
新控制台记录器()
), 
新WebUser()
);
控制器。创建(e);
}
}
公共静态类RepositoryBoostrapper
{
公共静态无效引导(容器)
{
容器。登记册通用(类型为(IGenericRepository),类型为(genericpository));
}
}
公共类实体
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串说明{get;set;}
公共Guid行行会{get;set;}
公共字节[]行版本{get;set;}
}
公共类控制器
{
专用只读IGenericRepository存储库;
私有只读IUserSecurity\u用户安全性;
公共控制器(IGenericRepository存储库、IUserSecurity用户安全)
{
_存储库=存储库;
_userSecurity=userSecurity;
}
//显示网页视图上的所有实体
公共行动结果索引(){
IEnumerable e=null;
User=User.Identity.Name;
if(_userSecurity.ValidateUser(用户))
{
e=_repository.ReadTs();
}
返回视图(e);
}
公共行动结果创建(实体e){
User=User.Identity.Name;
if(_userSecurity.ValidateUser(用户))
{
if(ModelState.IsValid)
{
_CreateT(e);
返回操作(“索引”);
}
}
返回视图(e);
}
}
公共接口IGenericRepository
{
T ReadTById(对象id);
IEnumerable reads();
无效更新集(T实体);
void CreateT(T实体);
无效删除(T实体);
}
公共类GenericRepository:IGenericRepository,其中T:class
{
私有只读客户端管理上下文\u上下文;
专用只读ILogger\u记录器;
公共GenericRepository(ClientManagementContext,ILogger记录器)
{
_上下文=上下文;
_记录器=记录器;
}
公共T ReadTById(对象id){
返回_context.Set().Find(id);
}
公共IEnumerable reads(){
返回_context.Set().AsNoTracking().AsEnumerable();
}
公共无效更新集(T实体){
var watch=Stopwatch.StartNew();
_context.Entry(entity.State=EntityState.Modified;
_SaveChanges();
_logger.Log(typeof(T).Name+
“于年签署”+
watch.elapsedmillesons+“ms.”;
}
公共void CreateT(T实体){
var watch=Stopwatch.StartNew();
_context.Entry(entity.State=EntityState.Added;
_SaveChanges();
_logger.Log(typeof(T).Name+
“于年签署”+
watch.elapsedmillesons+“ms.”;
}
公共无效删除(T实体){
_context.Entry(entity).State=EntityState.Deleted;
_SaveChanges();
}
}
公共类记录器
{
专用只读ILogger\u记录器;
公共记录器(ILogger记录器)
{
_记录器=记录器;
}
公共作废日志(字符串消息)
{
_logger.Log(消息);
}
}
公共接口ILogger
{
无效日志(字符串消息);
}
公共类控制台记录器:ILogger
{
公共作废日志(字符串消息)
{
控制台写入线(消息);
}
}
公共类数据库记录器:ILogger
{
公共作废日志(字符串消息)
{
//数据库日志记录
}
}
公共接口安全
{
bool-ValidateUser(用户);
}
公共类用户安全
{
私有只读IUserSecurity\u用户安全性;
公共用户安全(IUserSecurity UserSecurity)
{
_userSecurity=userSecurity;
}
公共图书馆(美国)
Begin SecurityRepositoryDecorator<Customer>.Create (calls `userSecurity.ValidateUser`)
    Begin LoggingRepositoryDecorator.Create (calls `Stopwatch.StartNew()`)
        Begin GenericRepository<Customer>.Create
        End GenericRepository<Customer>.Create
    End LoggingRepositoryDecorator.Create (calls ` this.logger.Log`)
End SecurityRepositoryDecorator<Customer>.Create