M A*_*ifi 3 c# domain-driven-design inversion-of-control
我有一个复杂的实体(Message),它有一个非常重要的构造函数(13个参数),其中一些参数依次为实体(Verb).
有许多事情我需要另一个实体的存储库(例如,对于某些默认值).
使用IoC并保持代码清洁/最佳实践的好方法是什么?
简化代码(我将默认动词列表作为由静态构造函数个人构建的静态对象,如果我的Message实体需要某种IRepositry,那么它是最简单的naff示例).
private static IVerbRepository verbRepository;
static Message()
{
using (IKernel kernel = new StandardKernel())
{
verbRepository = kernel.Get<IVerbRepository>();
}
}
public Message(int id, string precis,
DateTime created, DateTime validTo,
PriorityType priority, Source source, SID createdBy,
string content = null, string helpText = null,
DateTime? validFrom = null, bool emailOnExpiry = false,
IEnumerable<SID> targetUsers = null,
IOrderedEnumerable<MessageVerb> verbs = null) : base(id)
{
Verbs = verbs ??
new List<MessageVerb>
{
new MessageVerb(
verbRepository.GetByName("Acknowledge"), true,
string.Empty)
}.OrderBy(x => x.IsDefault);
Precis = precis;
Created = created;
ValidTo = validTo;
Priority = priority;
Source = source;
CreatedBy = createdBy;
Content = content;
HelpText = helpText;
ValidFrom = validFrom;
EmailOnExpiry = emailOnExpiry;
TargetUsers = targetUsers;
}
Run Code Online (Sandbox Code Playgroud)
通常的做法似乎是在构造函数中添加一个额外的参数.我不明白这是怎么回事?这意味着每次要创建消息时,都需要编写代码来检索存储库.假设你将它包装在一个工厂中,允许(逻辑上,如果不是真的)为消息引用提供不同的存储库是没有意义的吗?
编辑1
基于第一个解决方案,代码会喜欢这个,
public Message(IVerbRepository verbRepository ...) { }
Run Code Online (Sandbox Code Playgroud)
在同一域组件中的其他地方
public MessageService
{
private IVerbRepository VerbRepository {get; set;}
public static IOrderedEnumerable<MessageVerb> DefaultVerb {get;}
}
Run Code Online (Sandbox Code Playgroud)
在我的DDD之外高出很多(假设我的Web服务接受了消息的创建)
public class MessageWebService
{
private static IVerbRepository _verbRepository;
public void AddMessage(some parameters)
{
var message = new Message(_verbRepository, ...);
}
}
Run Code Online (Sandbox Code Playgroud)
有两种类型的IoC:您正在使用的服务定位器,以及您正在询问的依赖注入.
截至目前,Service Locator被认为是一种反模式,因为它引入了隐式依赖(通过查看类的公共接口无法弄清楚的依赖关系)并使测试更加困难.
另一方面,依赖注入没有这些问题,但在类声明中往往更冗长.
现在,关于你的问题.
我不明白这是怎么回事?
这是明确的.您可以看到您的课程取决于此服务或该服务.顺便说一句,你的课没有,它只使用动词库来定位默认动词(可以很容易地移出课堂外).
假设你将它包装在一个工厂中,允许(逻辑上,如果不是真的)为消息引用提供不同的存储库是没有意义的吗?
当你想到测试时它会这样做.您应该可以轻松地使用可测试的实现(存根)替换您的CUT所依赖的任何服务.
| 归档时间: |
|
| 查看次数: |
585 次 |
| 最近记录: |