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