如何在层次类中实现 IoC
我有一个包含类别对象的分层类别列表
public class Category
{
private int? ParentId = -1;
private Category _Parent = null;
public Category Parent
{
get
{
if (_Parent != null)
{
return _Parent;
}
if (this.ParentId.HasValue)
{
ICategoryRepository repo = new CategoryRepository();
var data = repo.Get(this.ParentId.Value);
_Parent = data;
}
return _Parent;
}
set
{
_Parent = null;
if (value == null)
{
ParentId = null;
}
else
{
ParentId = value.Id;
}
}
}
每个类别都有一个 Parent 属性,该属性延迟加载其父类别。
原始类别是使用 IRepository 接口加载的,因此我永远不必在业务层中新建存储库的新实例,它们是通过使用 Unity、ninject 等的依赖注入在应用程序级别提供的。
但在这里我看到一个实例我需要从业务层内创建存储库的实例。我该如何改变这个设计?
I have a hierarchical category list with Category objects
public class Category
{
private int? ParentId = -1;
private Category _Parent = null;
public Category Parent
{
get
{
if (_Parent != null)
{
return _Parent;
}
if (this.ParentId.HasValue)
{
ICategoryRepository repo = new CategoryRepository();
var data = repo.Get(this.ParentId.Value);
_Parent = data;
}
return _Parent;
}
set
{
_Parent = null;
if (value == null)
{
ParentId = null;
}
else
{
ParentId = value.Id;
}
}
}
Each category has a Parent property which lazy loads its parent category.
The original category is loaded using an IRepository interface so i never have to new up a new instance of a repository within the business layer, they are provide at the application level via Dependency injection using Unity, ninject etc.
But here i see an instance when i need to create an instance of a repository from within the business layer. How would i change this design?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可能会发现使用 Lazy方法很有用,如此处所述。这提出了一种非常好的方法,允许延迟加载,同时将持久性保留在业务对象类之外。
You might find using a Lazy<T> approach useful as explained here. This sets out quite a nice approach to allowing lazy loading whilst keeping persistence out of the business object class.
将“repo”移至 Category 类的私有成员。通过依赖注入设置它的值(不要在 getter 中新建它)。确保您的 IRepository.Get 方法与依赖项注入框架配合使用来创建它返回的对象(以便在这种情况下设置“repo”)。
Move 'repo' to be a private member on the Category class. Set it's value through dependency injection (don't new it up inside the getter). Ensure that your IRepository.Get method works with your dependency injection framework to create the objects that it returns (so that 'repo' will be set in this case).
有趣的问题。像这样的事情怎么样:
是的,类别本身实际上无法获得它自己的父级,这确实很糟糕。但似乎在检索原始类别的地方,您可以访问存储库,因此当您需要获取父对象时,只需继续使用存储库即可。
Interesting question. How about something like this:
Yes, the Category itself can't actually get it's own parent, and that does suck. But it does seem that where you're retrieving your original Category, you have access to the repository, so just continue using the repository when you need to get the parent object.
读完你的问题后,我立即想到的是罗伯特·利维的答案。如果您不想从业务层创建对 DI 框架的硬依赖,您可以将存储库设置为 Category 对象的属性,并在 repo.Get 中创建存储库对象时设置此属性。这感觉很糟糕,因为你不一定需要这个引用(如果你从不延迟加载),而且它是“硬编码的”,即不使用 DI 本身。作为替代方案,您可以使用延迟解析,如下所述 http: //msdn.microsoft.com/en-us/library/ff660854%28PandP.20%29.aspx 这样,当您创建 Category 对象时,您还会获得一个解析器委托,该 Category 对象将能够如果需要解析存储库实例,则调用。
Robert Levy's answer is what immediately comes to mind, after having read your question. If you don't want to create hard dependency on the DI framework from your business layer, you may make the repository a property of the Category object and set this property when you created the repository object in the repo.Get. This feels quite yucky though as you don't necessarily need this reference (if you never lazy load) and also it is "hard coded" i.e not using DI as such. As an alternate you can use deferred resolution as described here http://msdn.microsoft.com/en-us/library/ff660854%28PandP.20%29.aspx This way, when you create a Category object you also get a resolver delegate, that the Category object will be able to call should it need to resolve a repository instance.