C# 向Windsor IoC注册通用存储库时出现问题

C# 向Windsor IoC注册通用存储库时出现问题,c#,model-view-controller,repository,inversion-of-control,castle-windsor,C#,Model View Controller,Repository,Inversion Of Control,Castle Windsor,我对IoC还相当陌生,也许我对泛型和继承的理解还不够强,不足以胜任我的工作。你可能会发现这里一团糟。我有一个通用存储库基类: public class Repository<TEntity> where TEntity : class, IEntity { private Table<TEntity> EntityTable; private string _connectionString; private string _us

我对IoC还相当陌生,也许我对泛型和继承的理解还不够强,不足以胜任我的工作。你可能会发现这里一团糟。我有一个通用存储库基类:

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 ...
 ... }
这允许存储库类在其Save和Delete方法中引用这些方法。单元测试在模拟SqlClientRepository实例上运行良好,在真实数据库上也可以进行实时单元测试。但是,在MVC环境中:

   public class ClientController : Controller
   {
      private SqlClientRepository _clientRepository;

      public ClientController(SqlClientRepository clientRepository)
      {
         this._clientRepository = clientRepository;
      }
      public ClientController() { }
// ViewResult methods ...
... }
\u clientRepository始终为null。我正在使用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>

#{myConnStr}
我在Windsor配置文件中尝试了许多变体。我怀疑这更多的是上述代码中的设计缺陷。当我查看我的代码时,我突然想到,当向IoC容器注册组件时,也许服务必须始终是一个接口。可能是这个吗?有人有什么建议吗?提前谢谢

----修正案----

为了响应答案1,我添加了一个新的代码示例,因为它在下面的注释部分格式不正确

我可以让它工作:

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

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

public class SqlClientRepository : IClientRepository    { ... }
公共类ClientController:Controller
{
私人IClientRepository _clientRepository;
公共客户端控制器(iclientposition clientposition){…}
}
公共接口IClientPository:IRepository{…}
公共类SqlClientRepository:IClientRepository{…}
。。。但是现在我需要在SqlClientRepository中复制Save和Delete方法,而我的泛型存储库类的好处就消失了。一旦我再次尝试从存储库继承SqlClientRepository,如下所示:

public class SqlClientRepository : Repository<Client>, IClientRepository   { ... }
公共类SqlClientRepository:Repository,IClientRepository{…}
。。。控制器中_clientRepository的空值返回。我有没有办法做到这一点,还是不可能?我觉得我尝试了很多变化,但都做不好


再次感谢您的帮助。

不,服务不一定是一个接口,尽管通常应该是这样。服务是组件向外部世界公开的内容(如果有意义,请告诉我)

因此,
ClientController
的构造函数说“我依赖于
SqlClientRepository
服务”,这很糟糕(因为服务应该是抽象的(最好是接口)),但这不重要

您正在注册的组件(名为ClientRepository),您正在注册为
存储库
服务


希望到现在为止,你已经看到了问题所在
ClientComponent
需要
SqlClientRepository
,但您注册的组件不会将自身公开为
SqlClientRepository
,而是公开为
存储库
,因此Windsor认为:“好的,因为我没有服务用于
SqlClientRepository
,我将使用另一个构造函数来创建
ClientController
(解释温莎如何选择要使用的构造函数)

好的,我返回到以前的工作:类ClientController:Controller{private-iclientposition{clientposition;public-ClientController(iclientposition-clientposition){…}接口iclientposition:ireposition{…}类sqlclientposition:iclientposition{…}…但现在我需要复制SqlClientRepository中的Save、Delete方法。我的泛型存储库类的优点已丢失。这仍然会给_clientRepository一个空值:类SqlClientRepository:Repository,IClientRepository{…}有可能吗?谢谢。你能更新这个问题吗?评论中的代码是无法理解的。事实上,就像我说的那样,很简单,只要让
ClientController
依赖
存储库(或者更好的是
I存储库
)然后将您的
SqlClientRepository
注册为
IRepository
,以便它们匹配,就这样。好的,我终于得到了它,是的,它很简单。配置仍然如上所述,SqlClientRepository现在仍然从存储库继承,但我将ClientController设置为依赖于IRepository,并且一切工作都很好。谢谢您非常感谢你的帮助,非常感谢。
public class ClientController : Controller
   {
      private IClientRepository _clientRepository;
      public ClientController(IClientRepository clientRepository) { ... }
   }

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

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