2010-10-31 19 views
6
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); 
    } 
} 

kayıt ve çözmek için nasıl şimdi depo kayıt olun.StructureMap şöyle İçin açık genel tür

bir daha kolay ve daha iyi kayıt olacaktır:

For(typeof(IRepository<>)).Use(typeof(Repository<>)); 

Ancak bu işe yaramaz. StructureMap her zaman PluginFamily Core.Domain.Bases.Repositories.ITeamEmployeeRepository için tanımlanmış varsayılan bir örnek olmadığını söylüyor.

ben stackoverflow arandı ve yeni bir şey buldum:

Scan(x => 
{ 
    x.AssemblyContainingType(typeof(TeamEmployeeRepository)); 
    x.AddAllTypesOf(typeof (IRepository<>)); 
    x.ConnectImplementationsToTypesClosing(typeof(IRepository<>)); 
}); 

Ama yine aynı hata mesajı.

Depolarımı StructureMap 2.6.1.0 ile nasıl kaydettirmeliyim?

+0

Bu, doğrudan sorunuzu yanıtlamamakla birlikte, lütfen şu makaleye göz atın: http://stackoverflow.com/questions/4128640/how-to-remove-unit-of-work-functionality-from-repositories-using -ioc/41 32186 # 4132186. Havuz kalıbının uygulanmasının alternatif bir yolunu gösterir. Uygulama, depolarınızı bir iş biriminin arkasına saklar ve sadece bir “IUnitOfWorkFactory” kaydını yapmanız gerekir ve işiniz biter. – Steven

cevap

7

Bir çözüm buldum. Bu ayar ile size StructureMap TeamEmployeeRepository için ITeamEmployeeRepository mappping kuralını kullanmak demek çünkü WithDefaultConventions

Scan(x => 
{ 
    x.WithDefaultConventions(); 
    x.AssemblyContainingType(typeof(TeamEmployeeRepository)); 
    x.AddAllTypesOf(typeof(Repository<>)); 
    x.ConnectImplementationsToTypesClosing(typeof(IRepository<>)); 
}); 

, gösterilen kod önemli bir parçasıdır. Bu nedenle StructureMap, sınıfın I numaralı önek olmadan arabirimin adı gibi adlandırıldığı varsayımından hareket eder.

-1

Kısa bir süre önce küçük bir yeniden tasarım yaparak benzer bir şeyi çözdüm ve bu da her şeyi çok daha kolay hale getirdi. Bu sizin için de işe yarayabilir. Tasarımınızdan ITeamEmployeeRepository ve ILoanedItemRepository gibi belirli arabirimleri kaldırmayı deneyebilirsiniz. Bunu yaptığım yöntem uzatma yöntemleri kullanmaktı. Bana belirli türdeki depoları oluşturmasına izin bir IRepositoryFactory oluşturulan Bundan sonra

public static class RepositoryExtensions 
{ 
    public static TeamEmployee GetById(
     this IRepository<TeamEmployee> repository, int id) 
    { 
     return repository.Single(e => e.TeamEmployeeId == id); 
    } 

    public static IQueryable<Salesman> GetActiveSalesmen(
     this IRepository<ISalesmanRepository> repository) 
    { 
     return repository.Where(salesman => salesman.Active); 
    } 

    // etc 
} 

: İşte bir örnek

public interface IRepositoryFactory 
{ 
    IRepository<T> CreateNewRepository<T>(); 
} 

etapta bu arayüze sahip zaman bir uygulamasını oluşturmak kolaydır Bu fabrika, bir betonu Repository<T> beton oluşturmak için sorar. Eğer sadece IRepositoryFactory arayüzü tarafından somut RepositoryFactory kaydetmek zorunda Bu tasarım sayesinde

public class RepositoryFactory : IRepositoryFactory 
{ 
    public IRepository<T> CreateNewRepository<T>() 
    { 
     return ObjectFactory.GetInstance(typeof(Repository<T>)); 
    } 
} 

ve bitirdiniz: RepositoryFactory aşağıdaki gibi görünebilir. Eski tasarıma IRepository<ITeamEmployeeRepository> enjekte etmek yerine, şimdi IRepositoryFactory enjekte edip istemcinin CreateNewRepository<T> yöntemini aramasına izin verdiniz. Uzantı yöntemlerinin kullanılması nedeniyle, depodaki belirli yöntemlere başvurabilirsiniz.

Bunun bir diğer avantajı, her uygulamada ITeamEmployeeRepository numaralı belgede tanımladığınız yöntemleri yeniden uygulamanız gerekmez.

Bu tasarım, özellikle de IRepository<T> arabirimlerimin ifade ağaçlarından yararlandığından durumumda çok iyi çalıştı. Elbette bu tasarımın sizin için işe yarayıp yaramadığını görmek benim için mümkün değil ama umarım olacak.

İyi şanslar.

+0

"Bunun bir başka avantajı, her uygulamada ITeamEmployeeRepository üzerinde tanımladığınız yöntemleri yeniden uygulamanız gerekmemesidir." Durum böyle değil, çünkü Depo zaten standart CRUD öğelerini uyguluyor. Belirli ITeamEmployeeRepository'nin yalnızca belirli gereksinimleri vardır. – Rookian

+0

Belki de yanlış anladım, ama ekip çalışanlarına özel yöntemler için 'ITeamEmployeeRepository' kullanacağınızı hayal ettim. Bu yöntemler "Deposu " sınıfında hiçbir anlamı olmayacaktır. Bu arayüzde nesneye özgü yöntemlere sahip olduğunuzu varsayalım, çünkü yöntemleri olmayan bir arabirim çok kullanışlı olmayacaktır. Repository üzerinde hiçbir anlamı olmayan GetByYear veya CRUD işlemleri gibi şeyler. Normalde bu “ITeamEmployeeRepository” arayüzünün en az iki uygulaması olacaktır ... – Steven

+0

Üretim ortamınızda biri ve ünite test ortamınız için bir tane. Bu, bu durumlarda, "TeamEmployeeRepository" üretiminizde ve test test deposunda "GetByYear" öğesini uygulamanız gerektiği anlamına gelir. Bir uzantı yöntemiyle, kendinizi sadece birkaç kez yazmak zorunda kalmazsınız, aynı zamanda bu kodu da kapsamaz. Ama yine de, belki ihtiyaçlarınızı yanlış anlıyorum. – Steven

-2

Kendi ITypeScanner kodunuzu yaratmanız ve Scan() numaralı aramanızla kaydolabilmeniz gerekmektedir. Başlangıç ​​noktası olarak GenericConnectionScanner kaynak koduna bakın. IRepository<T>'u uygulayıp uygulamadıklarını görmek için türleri aramak yerine, IRepository<T>'u uygulayan bir arabirim uygulayıp uygulamadıklarını ve sonra bu arabirimin türünü kaydedip kaydetmediklerini göreceksiniz.

GÜNCELLEME: IRepository<T>'un tüm konuşması, gerçekten alakasız bir ayrıntı olduğunda bunu fazla düşünmemi sağladı. Sadece Rookian tarafından önerildiği gibi DefaultConventions tarayıcıyı kullanın.

2

Bu soruyu şu soru sormuştum: googling "structuremap resol generic". Mevcut cevaplar iyi ama karmaşıktır. basit bir cevap isteyenler için: arayüz ISome için ve uygulama sınıfının genel ISome <T> ve uygulama sınıfının Bazı <T> için biz

c.For(typeof(ISome<>)).Use(typeof(Some<>)) 

yazdıkça Bazıları

c.For<ISome>().Use<Some>() 

yazma Ve hepsi

var
İlgili konular