StructureMap - Wie sich zu registrieren und aufzulösen, ein offener generischer Typ
public interface IRepository<T> where T : Entity
{
void Delete(T entity);
T[] GetAll();
T GetById(int id);
void SaveOrUpdate(T enity);
void Merge(T entity);
}
public interface ITeamEmployeeRepository : IRepository<TeamEmployee>
{
PagedList<TeamEmployee> GetPagedTeamEmployees(int pageIndex, int pageSize);
}
public class Repository<T> : IRepository<T> where T : Entity
{
private readonly ISession _session;
protected Repository()
{
_session = GetSession();
}
public virtual void Delete(T entity)
{
_session.Delete(entity);
}
public virtual T[] GetAll()
{
return _session.CreateCriteria<T>().List<T>().ToArray();
}
public virtual T GetById(int id)
{
return _session.Get<T>(id);
}
public virtual void SaveOrUpdate(T enity)
{
_session.SaveOrUpdate(enity);
}
public void Merge(T entity)
{
_session.Merge(entity);
}
protected ISession GetSession()
{
return new SessionBuilder().GetSession();
}
}
public class TeamEmployeeRepository : Repository<TeamEmployee>, ITeamEmployeeRepository
{
public PagedList<TeamEmployee> GetPagedTeamEmployees(int pageIndex, int pageSize)
{
return GetSession().QueryOver<TeamEmployee>()
.Fetch(x => x.Employee).Eager
.Fetch(x => x.Team).Eager
.ToPagedList(pageIndex, pageSize);
}
}
Ich vorerst registrieren Sie das repository wie folgt:
For<ILoanedItemRepository>().Use<LoanedItemRepository>();
For<ITeamEmployeeRepository>().Use<TeamEmployeeRepository>();
For<IArticleRepository>().Use<ArticleRepository>();
For<ISalesmanRepository>().Use<SalesmanRepository>();
For<ISalesmanArticleRepository>().Use<SalesmanArticleRepository>();
For<IGoodsGroupRepository>().Use<GoodsGroupRepository>();
For<IEmployeeRepository>().Use<EmployeeRepository>();
Dies ist wirklich mühsam, vor allem, wenn es kommt entlang der neuen repositories.
Eine leichtere und bessere Registrierung wäre:
For(typeof(IRepository<>)).Use(typeof(Repository<>));
Aber das funktioniert nicht. StructureMap ist jedesmal sagt mir, dass kein Standard-Instanz definiert PluginFamily Kern.Domain.Basen.Repositories.ITeamEmployeeRepository.
Suchte ich auf stackoverflow gefunden und etwas neues:
Scan(x =>
{
x.AssemblyContainingType(typeof(TeamEmployeeRepository));
x.AddAllTypesOf(typeof (IRepository<>));
x.ConnectImplementationsToTypesClosing(typeof(IRepository<>));
});
Aber immer noch die gleiche Fehlermeldung.
Wie kann ich mich registrieren, meine Repositorys mit StructureMap 2.6.1.0?
- Während dies nicht direkt Ihre Frage zu beantworten, werfen Sie bitte einen Blick auf diesen Artikel: stackoverflow.com/questions/4128640/.... Es zeigt eine alternative Art und Weise der Umsetzung der repository-pattern. Die Umsetzung verbirgt Ihre Repositorys hinter einer Einheit von Arbeit und Sie brauchen nur zu registrieren
IUnitOfWorkFactory
und du bist fertig.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich' ve eine Lösung gefunden.
WithDefaultConventions ist der wichtige Teil von dem gezeigten code, denn mit dieser Einstellung, die Sie sagen StructureMap verwenden die Konvention der Abbildung ITeamEmployeeRepository zu TeamEmployeeRepository. So StructureMap gehen von der Annahme aus, dass die Klasse, die den Namen der name der Schnittstelle, die ohne das Präfix ich.
Fand ich diese Frage googeln "structuremap beheben generic". Die vorhandenen Antworten sind gut, aber Komplex. Für diejenigen, die eine einfache Antwort: für ISome-Schnittstelle und implementierende Klasse Einige, die wir schreiben
Während für generische ISome<T> und die Umsetzung Klasse Einige<T> wir schreiben
Und das ist alles
Vor kurzem habe ich gelöst, etwas ähnliches, indem Sie einen kleinen redesign, das machte alles so viel einfacher. Dies könnte auch für Sie arbeiten. Sie könnten versuchen, entfernen die spezifischen Schnittstellen wie
ITeamEmployeeRepository
undILoanedItemRepository
von Ihrem design. Die Art, wie ich Tat dies durch den Einsatz von extension-Methoden. Hier ist ein Beispiel:Danach erstellte ich eine
IRepositoryFactory
dass mir erlaubt, zu erstellen Repositorys eines bestimmten Typs:Wenn diese Schnittstelle im Markt ist es einfach zu erstellen Sie eine Implementierung dieser factory, fragt der container zu erstellen, ein konkretes
Repository<T>
. DieRepositoryFactory
könnte wie folgt Aussehen:Mit diesem design, Sie haben nur zu registrieren, die konkrete
RepositoryFactory
durch seineIRepositoryFactory
Schnittstelle, und Sie sind fertig. Statt der InjektionIRepository<ITeamEmployeeRepository>
im alten design, die Sie jetzt injizieren einenIRepositoryFactory
und lassen Sie den Kunden nennen, dieCreateNewRepository<T>
Methode. Wegen der Verwendung von extension-Methoden, die Sie aufrufen können, geben Sie spezifische Methoden für das repository.Ein weiterer Vorteil dieser ist, dass Sie nicht brauchen, um re-implementieren Sie die Methoden, die Sie zunächst definiert
ITeamEmployeeRepository
auf jeden Umsetzung.Dieses design funktionierte sehr gut in meiner situation, vor allem, weil meine
IRepository<T>
Schnittstellen nutzen Ausdruck Bäume. Natürlich ist es nicht möglich für mich, um zu sehen, ob ein solches design für Sie arbeitet, aber ich hoffe, es wird.Glück.
ITeamEmployeeRepository
für team Mitarbeiter bestimmte Methoden. Diese Methoden haben keine Bedeutung in derRepository<T>
Klasse. Ich nehme an, Sie haben Entität spezifischen Methoden auf die Schnittstelle, weil ein interface ohne Methoden würde nicht sehr hilfreich sein. Dinge wieGetByYear
oder CRUD-Operationen, die keine Bedeutung haben auf Repository<T>. Normalerweise würden Sie mindestens zwei Implementierungen diesesITeamEmployeeRepository
- Schnittstelle...GetByYear
sowohl in Ihrer ProduktionTeamEmployeeRepository
und die Verwendung von test-repository. Mit einer Erweiterung Methode sparen Sie nicht nur sich selbst aus, die zu schreiben es mehrere Male, aber es ermöglicht es Ihnen, dass zur Deckung der code. Aber nochmal, vielleicht habe ich missverstanden, Ihre Bedürfnisse.Müssen Sie erstellen Ihre eigenen
ITypeScanner
und registrieren Sie es in IhremScan()
nennen. Blick auf den Quellcode vonGenericConnectionScanner
als Ausgangspunkt. Statt der Suche den Typen zu sehen, ob Sie umzusetzenIRepository<T>
Sie schauen, um zu sehen, wenn Sie implementieren eine Schnittstelle implementiert, dassIRepository<T>
, und registrieren Sie den Typ für die Schnittstelle.UPDATE: Alle reden von
IRepository<T>
hatte mich über-denken, das, wenn es wirklich eine irrelevante details. Verwenden Sie einfach die DefaultConventions scanner vorgeschlagen von Rookian.