Frage

Im Moment versuche ich einen Weg, um herauszufinden, Dinge zu tun klüger, und im Laufe dabei alles, was ich geschaffen habe, ist zu tun, um eine volle Flasche Excedrin in einem einzigen Tag.

Angenommen, ich habe eine Schnittstelle namens IRepository wie so.

 public interface IRepository<T>
 {
    T Get(int id);
    void Add(T value);
    void Update(T value);
    void Delete(T value);
    ...
 }

Und davon ausgehen, ich habe eine Implementierung wie

public class NHibernateRepository<T>
{
    ...
}

Nun, das ist alles schön und gut, kann ich tun alle meine grundlegenden Operationen gegen das Repository alle CRUD-Funktionalität zu unterstützen, aber ich spezialisierte Operationen möchten, so gehe ich davon eine Schnittstelle wie folgt:

public interface IUserRepository : IRepository<User>
{
     IList<User> GetUsersByRole(Role role);
}

Und eine Implementierung wie so:

public class UserRepository : NHibernateRepository<User>, IUserRepository
{
    ....
}

Ok, so dass die Grundeinstellung ist, jetzt gibt es noch eine weitere Sache, die ich tun möchte. Ich möchte haben Protokollierung und Transaktion und Dinge wie das alles transparent. Also, was ich zu tun ist, möchte einen Dependency Injection-Framework wie Schloss Windsor oder StructureMap verwenden, so dass, wenn ich für IRepository fragen, ich werde es von einem LoggingRepository und einem TransactionRepository gewickelt bekommen, von denen beide IRepository implementieren.

Also, was ich will, ist, etwas zu tun wie folgt aus:

IUserRepository repository = container.Resolve< IUserRepository>();

und haben sie eine Benutzer-Repository zurück, die in dem Logging und Transaktions Dekorateure gewickelt sind, aber ich kann so nicht denken, dass dies jemals funktionieren. Der einzige Weg, ich immer diese an die Arbeit denken kann, ist durch wie eine solche Umsetzung UserRepository:

public class UserRepository : DecoratorRepository<T>, IUserRepository
{
    protected IRepository<T> Repository { get; set; }

    public UserRepository(IRepository<T> innerRepository)
    {
        Repository = innerRepository;
    }
}

Dies würde bedeuten, dass wir Dependency Injection verwenden würden ein dekoriertes Repository zu erstellen und dass in den Konstruktor des UserRepository passieren und dann verwenden, die als Repository, in dem wir Operationen gegen laufen. Dies würde funktionieren, aber ich denke immer noch nicht, es ist ideal.

Also, meine Frage ist, bin ich recht, dass dies der einzige Weg, dies zu tun, oder bin ich das nicht richtig verstehen oder einfach nur etwas, das alle zusammen fehlt. Auch, wenn Sie haben, bevor Sie gegen dieses Problem Vorfeld, wie haben Sie Lösungen für dieses Problem?

War es hilfreich?

Lösung

Wenn Sie vorhaben, Dekorateure benutzen , dass etwa richtig klingt. Jeder Dekorateur würde mit dem Argument IRepository einen Konstruktor haben und rufen Sie die Protokollierung oder Transaktionscode um Anrufe an die innere Repository, das es zu dekorieren.

Als Alternative könnte man bedenkt, aber das habe ich sehr wenig Erfahrung mit Aspect ist Programming Oriented. In diesem Szenario wenden Sie Attribute auf Ihre Klassen, die zeigen, was die Protokollierung oder Transaktions Methoden, die Sie verwenden möchten. An einem gewissen Punkt dieser Methoden in Ihren Code spannen bekommen, kann dies entweder als zusätzliche Kompilierung durchgeführt werden, oder in dem Fall des SpringFramework.net zum Zeitpunkt der Injektion.

Andere Tipps

Könnten Sie nicht eine LoggingRepository abstrakte Basisklasse, die für Ihre verschiedenen Get anmelden würde behandeln, Hinzufügen, Aktualisieren, Löschen, machen sie virtuell und dann von ihnen erben?

Ich bin mir nicht sicher, ob das, was Problem, das Sie versuchen, obwohl zu lösen, wie ich glaube, würde man dies versucht haben kann? Sie könnten auch in Transaktionen wickeln, obwohl die meisten wahrscheinlich, dass Sie, dass in Ihrem NHibernateRepository tun wollen würde.

Dieser Blog wie eine Lösung sieht Ihr Problem. Es ist im Grunde das gleiche Design mit Ausnahme statt mit einem geschützten IRepository Sie es privat nur lesbar zu machen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top