簡體   English   中英

Autofac通用裝飾器鏈接

[英]Autofac generic decorator linking

我有一個通用的RepositoryDecorator<T>裝飾器。 MyRepositoryDecoratorBase<T>NoteRepository<Note>繼承自它。

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

注意:我正在使用它來注冊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中的解決方案- 注冊多個裝飾器

但無法讓它發揮作用。 我有一種感覺,我的存儲庫的通用注冊正在阻礙。

以下工作但我想自動鏈接多個裝飾器而不對其進行硬編碼。

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

我得到它的工作如下

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM