2016-11-08 3 views
1

Ich habe eine generische RepositoryDecorator<T> Dekorateur. MyRepositoryDecoratorBase<T> und NoteRepository<Note> erben von ihm.Autofac generische Dekorateur Verknüpfung

IRepository<T> ist eine Schnittstelle und Repository<T> ist eine Implementierung davon. Dies wird auch mit Autofac registriert, wie im Codebeispiel gezeigt.

Der Versuch, Autofac zu verwenden, um eine Instanz von MyRepositoryDecoratorBase jedes Mal zu generieren, wenn eine Instanz von NoteRepository angefordert wird.

So kann ich die Dekorateure für Querschneidungen wie Protokollierung verknüpfen.

Zusammenfassung Decorator

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

} 

Generisches 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."); 
    } 
} 

Hinweis Decorator

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

Hinweis: Ich verwende diese

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

Ich habe in einer Basis-Repository-Implementierung für IRepository registrieren erhalten Autofac - Register multiple decorators

an der Lösung gesucht, aber konnte es nicht funktioniert. Ich habe das Gefühl, dass meine generische Registrierung von Repository in die Quere kommt.

Folgendes funktioniert, aber ich möchte mehrere Decorators automatisch verknüpfen, ohne es hart zu codieren.

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

Antwort

0

Ich habe es als Arbeits

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

folgt Und es

 //Get ioc container to create our repository 
     NoteRepository rep = resolver.Resolve<NoteRepository>(); 
mit