2013-03-15 63 views
1

我下面嘗試Repository模式實現解決歧義

interface IRepository<T> 
{ 
    IQueryable<T> All { get; } 
    T Find(object id); 
    void Insert(T model); 
} 

那麼我IAdminRepository定義如下

interface IAdminRepository : IRpository<Role>, IRepository<User> 
{ 
} 

public class AdminRepository:IAdminRepository 
{ 
    IQueryable<User> IRepository<User>.All 
    { 
     get { throw new NotImplementedException(); } 
    } 

    User IRepository<User>.Find(object id) 
    { 
     throw new NotImplementedException(); 
    } 

    void IRepository<User>.Insert(User model) 
    { 
     throw new NotImplementedException(); 
    } 

    IQueryable<Role> IRepository<Role>.All 
    { 
     get { throw new NotImplementedException(); } 
    } 

    Role IRepository<Role>.Find(object id) 
    { 
     throw new NotImplementedException(); 
    } 

    void IRepository<Role>.Insert(Role model) 
    { 
     throw new NotImplementedException(); 
    } 
} 

在我的業務層,我使用基於接口調用。

public interface IAdminService 
{ 
    bool CreateUser(User user);   
    List<User> GetAllUsers(); 
} 

public class AdminService : IAdminService 
{ 
    private readonly IAdminRepository AdminRepository; 

    public AdminService(IAdminRepository _adminRepository) 
    { 
     AdminRepository = _adminRepository; 
    } 

    public bool CreateUser(User user) 
    { 
     AdminRepository.Insert(user); 
     return true; 
    } 

    public List<User> GetAllUsers() 
    { 
     return AdminRepository.All; // Here is error 
    } 
} 

Error: Ambiguity between IRepository.All & IRepository.All.

如何解決這個問題?以這種方式使用Repository Pattern的方法有什麼問題?

+0

您的IAdminRepository從IRepository 繼承IRepository ,因此當您執行AdminRepository.All時,它不知道應該調用哪個.All,因爲它同時具有用戶和角色。你應該做的是讓你的IAdminRepository類型T並繼承IRepository 2013-03-15 09:59:26

+0

@ManishMishra,你是說AdminRepository ?它在這裏沒有任何意義:) – Billa 2013-03-15 10:04:57

回答

1

我想這行

return AdminRepository.All; // Here is error 

應該

return ((IRepository<User>)AdminRepository).All.ToList(); 

你可能注意到了,你會不會已經能夠申報.All沒有明確寫你實現的接口。這是因爲,對於給定的類,具有相同名稱的兩個屬性不能具有不同的返回類型。

調用時是一樣的。你必須確切地告訴你正在調用哪個屬性。這是通過將對象投射到所需的界面來完成的。

無論如何,看來你會最終實現所有實體類型的存儲庫。對於可以從同一機制中檢索的實體類型,您應該僅實施IRepository<T>一次。

如果您希望您的存儲庫僅適用於某些類,則可以使用接口標記這些類。比方說IEntity

public interface IEntity 
{ 
} 

然後

public interface IRepository<T> where T:IEntity 
{ 
    IQueryable<T> All { get; } 
    T Find(object id); 
    void Insert(T model); 
} 

你甚至可以有DB庫只適用於實體你會標記爲DB實體,像這樣:

public interface IDbEntity: IEntity 
{ 
} 


public class DbRepository<T> : IRepository<T> where T:IDbEntity 
{ 
    public IQueryable<T> All { get; private set; } 
    public T Find(object id) 
    { 
     throw new NotImplementedException(); 
    } 

    public void Insert(T model) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+1

好猜,但錯過了一個解釋*爲什麼*。 – JustAnotherUserYouMayKnow 2013-03-15 10:06:45

+0

@JustAnotherUserYouMayKnow good point :-)我會盡快添加一個 – jbl 2013-03-15 10:09:50

1

一個簡單的方法來消除歧義該調用是創建混疊方法:

public class AdminRepository : IAdminRepository { 

    public IQueryable<User> AllUsers { 
    get { throw new NotImplementedException(); } 
    } 

    public IQueryable<Role> AllRoles { 
    get { throw new NotImplementedException(); } 
    } 

    IQueryable<User> IRepository<User>.All { 
    get { return AllUsers; } 
    } 

    IQueryable<Role> IRepository<Role>.All { 
    get { return AllRoles; } 
    } 

    ... 
} 
+1

這看起來非常棒。謝謝 – Billa 2013-03-17 05:18:33