繁体   English   中英

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

[英]Problem Registering a Generic Repository with Windsor IoC

我对IoC还是很陌生,也许我对泛型和继承的理解不足以实现我想要做的事情。 您可能会发现这很混乱。 我有一个通用的Repository <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 ...
 ... }

和一个继承存储库的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类提供了一些通用方法,例如Save <TEntity>,Delete <TEntity>等,我希望所有我的存储库派生类都可以共享。

TEntity参数限于IEntity接口:

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

这允许Repository类在其Save和Delete方法中引用这些方法。 单元测试可以在模拟SqlClientRepository实例上正常运行,也可以在真实数据库上正常运行单元测试。 但是,在MVC上下文中:

   public class ClientController : Controller
   {
      private SqlClientRepository _clientRepository;

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

..._ 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>

我在Windsor配置文件中尝试了许多变体。 我怀疑这更多是上述代码中的设计缺陷。 在查看代码时,我发现在向IoC容器注册组件时,服务可能始终是接口。 这可能吗? 有人有建议吗? 提前致谢。

----修订----

作为对答案1的回应,我添加了一个新的代码示例,因为在下面的注释部分中该格式无法正确格式化。

我可以使它工作:

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

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

public class SqlClientRepository : IClientRepository    { ... }

...但是现在我需要在SqlClientRepository中复制我的Save和Delete方法,并且我的通用Repository类的好处也丢失了。 一旦我尝试让SqlClientRepository再次从Repository <Client>继承,如下所示:

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

...我的_clientRepository控制器中的空值返回。 有什么办法可以做到吗? 我觉得我尝试了许多变体,但做对了。

再次感谢你的帮助。

不,服务通常不必是接口。 服务是组件向外界公开的东西( 请参阅doco ,让我知道是否有意义)。

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

您正在注册的组件 (名为ClientRepository),正在注册为Repository<Client> service

希望到目前为止,您已经看到了问题所在。 ClientComponent需要SqlClientRepository ,但是您已注册的组件不会将自身显示为SqlClientRepository ,而是显示为Repository<Client> ,因此Windsor认为: “好吧,因为我没有SqlClientRepository 服务 ,所以我将使用其他构造函数来创建ClientController请参阅doco以获取有关Windsor如何选择要使用的构造函数的说明)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM