0

我是相當新的國際奧委會也許我的泛型和繼承的理解是不是我想要做的足夠強大。你可能會覺得這是一團糟。我有一個通用的存儲庫<TEntity>基類:問題註冊一個通用存儲庫溫莎國際奧委會

public class Repository<TEntity> where TEntity : class, IEntity 
    { 
     private Table<TEntity> EntityTable; 
     private string _connectionString; 
     private string _userName; 
     public string UserName 
     { 
     get { return _userName; } 
     set { _userName = value; } 
     } 

     public Repository() {} 

     public Repository(string connectionString) 
     { 
     _connectionString = connectionString; 
     EntityTable = (new DataContext(connectionString)).GetTable<TEntity>(); 
     } 

     public Repository(string connectionString, string userName) 
     { 
     _connectionString = connectionString; 
     _userName = userName; 
     EntityTable = (new DataContext(connectionString)).GetTable<TEntity>(); 
     } 
// Data access methods ... 
... } 

和繼承Repository中SqlClientRepository:

public class SqlClientRepository : Repository<Client> 
    {  
private Table<Client> ClientTable; 
      private string _connectionString; 
      private string _userName; 

      public SqlClientRepository() {} 

      public SqlClientRepository(string connectionString) : base(connectionString) 
      { 
      _connectionString = connectionString; 
      ClientTable = (new DataContext(connectionString)).GetTable<Client>(); 
      } 

      public SqlClientRepository(string connectionString, string userName) 
      : base(connectionString, userName) 
      { 
      _connectionString = connectionString; 
      _userName = userName; 
      ClientTable = (new DataContext(connectionString)).GetTable<Client>(); 
      } 
    // data access methods unique to Client repository 
    ... } 

repository類提供了一些仿製藥的方法,如保存<TEntity>,刪除<TEntity>,我希望我所有的存儲庫派生類可以共享。

的TEntity參數被約束到IEntity接口:

public interface IEntity 
    { 
     int Id { get; set; } 
     NameValueCollection GetSaveRuleViolations(); 
     NameValueCollection GetDeleteRuleViolations(); 
    } 

這允許存儲庫類引用其內保存這些方法和刪除的方法。單元測試做工精細的模擬SqlClientRepository實例,以及真實的數據庫直播單元測試。然而,在MVC方面:

public class ClientController : Controller 
    { 
     private SqlClientRepository _clientRepository; 

     public ClientController(SqlClientRepository clientRepository) 
     { 
     this._clientRepository = clientRepository; 
     } 
     public ClientController() { } 
// ViewResult methods ... 
... } 

... _clientRepository總是。我使用Windor Castle作爲IoC容器。這裏是配置:

<component id="ClientRepository" service="DomainModel.Concrete.Repository`1[[DomainModel.Entities.Client, DomainModel]], DomainModel" 
     type="DomainModel.Concrete.SqlClientRepository, DomainModel" lifestyle="PerWebRequest"> 
     <parameters> 
     <connectionString>#{myConnStr}</connectionString> 
     </parameters> 
    </component> 

我已經在Windsor配置文件中嘗試了很多變化。我懷疑這是上面代碼中更多的設計缺陷。正如我期待在我的代碼,它發生,我認爲與IoC容器註冊組件時,也許服務必須始終是一個接口。這可能嗎?有人有建議嗎?提前致謝。

---- ----修訂

針對答1,我已經追加了新的代碼示例,因爲它不會在下面的評論部分正確地格式化。

我能得到這個工作:

public class ClientController : Controller 
    { 
     private IClientRepository _clientRepository; 
     public ClientController(IClientRepository clientRepository) { ... } 
    } 

public interface IClientRepository : IRepository<Client> { ... } 

public class SqlClientRepository : IClientRepository { ... } 

...但現在我需要重複我的保存和刪除SqlClientRepository內的方法和我的通用庫類的丟失帶來的好處。有一次,我嘗試和具有資源庫<客戶> SqlClientRepository繼承再次,像這樣:

public class SqlClientRepository : Repository<Client>, IClientRepository { ... } 

...控制器回報_clientRepository我的空值。有沒有辦法做到這一點,或者這是不可能的?我覺得我已經嘗試了很多變化,並且無法做到。

再次感謝您的幫助。

+0

這很簡單,其實 - 就像我說的 - 只是使'ClientController'取決於'庫'(或更好,但'IRepository ')和寄存器你的'SqlClientRepository'作爲'IRepository ',以便它們匹配,就是這樣。 – 2010-06-13 11:25:16

+0

好的,我終於明白了,是的,這很簡單。配置仍然如上,SqlClientRepository現在仍然繼承自Repository ,但我設置ClientController依賴於IRepository ,並且一切正常。 非常感謝您的幫助。非常感謝。 – Robin 2010-06-13 15:02:41

回答

2

沒有,服務不必須是一個接口,但通常它應該。服務是什麼成分暴露給外界(see the doco,讓我知道,如果這是有道理的)。

所以,你ClientController的構造說:「我靠SqlClientRepository服務這是不好的(因爲服務應該是抽象的(最好接口)),但是這是除了點。

組件你註冊(名爲ClientRepository),你註冊成爲Repository<Client>服務

希望現在你看到了什麼問題。 ClientComponent預計SqlClientRepository,但您已經註冊的組件本身不公開爲SqlClientRepository,但作爲Repository<Client>,因此溫莎認爲:「好吧,因爲我沒有服務SqlClientRepository我會用其他的構造函數,創建ClientControllersee the doco用於解釋如何使用溫莎精選其中的構造函數)

+0

好的,我已經回到之前的工作: class ClientController:Controller {0}私有IClientRepository _clientRepository; 公共ClientController(IClientRepository clientRepository){...}} 接口IClientRepository:IRepository {...} 類SqlClientRepository:IClientRepository {...} ......但我現在需要重複我的保存,刪除SqlClientRepository中的方法。我的通用Repository類的好處丟失了。這仍然給_clientRepository一個空值: 類SqlClientRepository:存儲庫,IClientRepository {...} 這可能嗎?謝謝。 – Robin 2010-06-11 14:18:08

+0

你能更新這個問題嗎?評論中的代碼是不可讀的 – 2010-06-11 15:18:37

+0

好吧,我已經更新了我上面的原始帖子。 – Robin 2010-06-12 01:34:26