2016-11-08 37 views
1

我有一个通用的RepositoryDecorator<T>装饰器。 MyRepositoryDecoratorBase<T>NoteRepository<Note>从它继承。Autofac通用装饰器链接

IRepository<T>是一个接口,Repository<T>是它的一个实现。这也是使用Autofac注册的,如代码示例中所示。

每次请求NoteRepository的实例时,都试图使用autofac生成MyRepositoryDe​​coratorBase的实例。

这样我就可以链接装饰器来处理横切问题,如日志记录。

摘要装饰

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); 
    } 

} 

通用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); 
    } 
} 

注:我使用这Autofac - Register multiple decorators

注册一个基础库实施IRepository

  //This will resolve and bind storage types to a concrete repository of <T> as needed 
     builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).SingleInstance(); 

我已经看过了解决方案,但不能得到它的工作。我有一种感觉,我的Repository的通用注册正在开始。

以下工作,但我想自动链接多个装饰器,而不需要对其进行硬编码。

NoteRepository rep = new NoteRepository(new MyRepositoryDecoratorBase<Note>(container.Resolve<IRepository<Note>>())); 

回答

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>();