我有一个通用的RepositoryDecorator<T>
装饰器。 MyRepositoryDecoratorBase<T>
和NoteRepository<Note>
正在继承。
IRepository<T>
是一个接口,Repository<T>
是它的一个实现。这也是使用Autofac注册的,如代码示例所示。
每次要求NoteRepository的实例时,尝试使用autofac生成MyRepositoryDecoratorBase的实例。
通过这种方式,我可以将装饰器与日志记录等交叉问题联系起来。
抽象装饰
public abstract class RepositoryDecorator<TAggregate>:IRepository<TAggregate>
where TAggregate:AggregateRoot, new()
{
protected readonly IRepository<TAggregate> Repository;
protected RepositoryDecorator(IRepository<TAggregate> repository)
{
Repository = repository;
}
public virtual TAggregate GetById(Guid Id)
{
return Repository.GetById(Id);
}
public virtual void Save(TAggregate aggregate)
{
Repository.Save(aggregate);
}
}
Generic LoggingDecorator
public class MyRepositoryDecoratorBase<T>:RepositoryDecorator<T> where T : AggregateRoot, new()
{
private DateTime _commitStartTime;
public MyRepositoryDecoratorBase(IRepository<T> repository) : base(repository)
{
}
public override T GetById(Guid Id)
{
BeforeLoadAggregate(Id);
var result = base.GetById(Id);
AfterLoadingAggregate(result);
return result;
}
public override void Save(T aggregate)
{
BeforeSaveAggregate(aggregate);
base.Save(aggregate);
AfterSavingAggregate(aggregate);
}
protected void BeforeLoadAggregate(Guid id)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"Loading {id} ...");
Console.ForegroundColor = ConsoleColor.White;
}
protected void AfterLoadingAggregate(T aggregate)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"Loaded {aggregate.GetType()} ...");
Console.ForegroundColor = ConsoleColor.White;
}
protected void BeforeSaveAggregate(T aggregate)
{
_commitStartTime = DateTime.Now;
Console.WriteLine($"Trying to commit {aggregate.GetUncommittedChanges().Count()} events to storage.");
}
protected void AfterSavingAggregate(T aggregate)
{
Console.WriteLine($"Committed in {DateTime.Now.Subtract(_commitStartTime).TotalMilliseconds} ms.");
}
}
注意装饰器
public class NoteRepository:RepositoryDecorator<Note>
{
public NoteRepository(IRepository<Note> repository) : base(repository)
{
}
public override void Save(Note aggregate)
{
LogManager.Log("Saving Note...", LogSeverity.Information);
base.Save(aggregate);
LogManager.Log("Note Saved...", LogSeverity.Information);
}
}
注意:我使用它来注册IRepository的基础存储库实现
//This will resolve and bind storage types to a concrete repository of <T> as needed
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).SingleInstance();
我查看了Autofac - Register multiple decorators
中的解决方案但无法让它发挥作用。我有一种感觉,我的存储库的通用注册正在阻碍。
以下有效但我想自动链接多个装饰器而不对其进行硬编码。
NoteRepository rep = new NoteRepository(new MyRepositoryDecoratorBase<Note>(container.Resolve<IRepository<Note>>()));
答案 0 :(得分:0)
我按照以下方式工作
//This will resolve and bind storage types to a concrete repository of <T> as needed
builder.RegisterGeneric(typeof(Repository<>))
.Named("handler",typeof(IRepository<>))
.SingleInstance();
//This will bind the decorator
builder.RegisterGenericDecorator(
typeof(MyRepositoryDecorator<>),typeof(IRepository<>),fromKey: "handler");
//Register NoteRepository
builder.RegisterType<NoteRepository>();
使用它
//Get ioc container to create our repository
NoteRepository rep = resolver.Resolve<NoteRepository>();