C# 向Windsor IoC注册通用存储库时出现问题
我对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
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 { ... }