1

这个问题可能更适合程序员堆栈。如果是这样,我会移动它。不过,我想我可能在这里得到更多答案。在域类中使用服务定位器模式有时可以吗?

到目前为止,我的域中的所有接口依赖项都是使用执行程序集中的DI来解决的,目前它是.NET MVC3项目(+ Unity IoC容器)。不过,我已经运行了一个场景,我认为服务定位器可能是更好的选择。

域中存在一个存储(缓存)来自URL的内容的实体。具体而言,它存储来自元数据URL的SAML2 EntityDescriptor XML。我有一个单一的方法的接口IConsumeHttp:

public interface IConsumeHttp 
{ 
    string Get(string url); 
} 

当前实现使用静态WebRequest类在System.Net:

public class WebRequestHttpConsumer : IConsumeHttp 
{ 
    public string Get(string url) 
    { 
     string content = null; 
     var request = WebRequest.Create(url); 
     var response = request.GetResponse(); 
     var stream = response.GetResponseStream(); 
     if (stream != null) 
     { 
      var reader = new StreamReader(stream); 
      content = reader.ReadToEnd(); 
      reader.Close(); 
      stream.Close(); 
     } 
     response.Close(); 
     return content; 
    } 
} 

哪个缓存XML内容的实体存在作为非根在一个更大的实体集合中。对于剩余的聚合,我实现了一个有点大的Facade模式,这是MVC控制器的公共端点。我可以注入IConsumeHttp依赖在门面构造像这样:

public AnAggregateFacade(IDataContext dataContext, IConsumeHttp httpClient) 
{ 
    ... 

我这个看到的问题是,只有一个门面方法有这个接口的依赖关系,因此它似乎傻注入它的整个门面。 WebRequestHttpConsumer类的对象创建不应该增加很多开销,但是域并不知道这一点。

我正在考虑将实体的所有缓存逻辑移出到单独的静态工厂类中。不过,代码将取决于IConsumeHttp。所以我正考虑在静态工厂方法中使用静态服务定位器来解析IConsumeHttp,但只有当需要初始化或刷新缓存的XML时。

我的问题:这是一个坏主意吗?在我看来,确保XML元数据得到适当缓存应该是域的责任。域作为其他相关操作的一部分定期执行此操作(例如获取SAML Authn请求的响应,更新SAML实体ID或元数据URL等)。或者我只是担心它太多?

+1

相关:http://stackoverflow.com/questions/4835046/why-not-use-an-ioc-container-to-resolve-dependencies-for-entities-business-objec – Steven 2012-03-21 15:11:20

+0

IMO这是一个有效的问题所以。 – Steven 2012-03-21 15:11:43

+0

@Steven感谢您的链接,信任投票以及您的博客,了解如何使用您的架构的查询+命令端。非常有趣的东西。 – danludwig 2012-03-21 16:31:30

回答

0

它似乎对我来说,它应该是该域的责任 确保XML元数据进行适当缓存

我不知道这件事,除非你的域名实际上是关于元数据操作,http请求等。对于具有非技术领域的“正常”应用程序,我宁愿在基础结构/技术服务层处理缓存问题。

我这个看到的问题是,只有一个门面方法有这个接口的 依赖,因此它似乎傻注入它的 整个门面

显然,外墙通常因为他们自然倾向于指向许多依赖关系,所以不适合构造器注入。您可以考虑其他类型的注射,或者如您所指,使用定位器。但是我想要做的是问自己一个Facade是否真的合适,并考虑使用更细粒度的对象,而不是所有控制器中的同一个大接口。这将允许更多的模块化和临时注入,而不是预先大量增加大量物体。

但是,这可能只是因为我不是一个大风扇门面;)

+0

感谢您的输入。该域不是关于HTTP,并且不引用System.Web,MVC或任何类似的dll,这就是为什么我将HttpConsumer包装在界面中的原因。这是它在域中使用的唯一情况。控制器处理SAML http事件并使用操作系统的元数据,例如发送Authn请求。看起来好像让控制器确保域名有正确的XML太细,给客户太多的责任。该网域已经知道该网址,并且可以自行完成。你确实有一点,我正在研究其他模式。 – danludwig 2012-03-22 14:41:00

0

在您的评论对@ ian31,你提到“仿佛使控制器确保域具有正确的XML过于详尽,给客户太多的责任“。出于这个原因,我宁愿控制器要求它的服务/存储库(它可以实现缓存层)为当前XML的正确&。对我来说,这个责任是很多要问的域实体。然而,如果你对你所描述的责任没有问题,并且你提到创建对象没有太多开销,我认为将IConsumeHttp留在实体中是没有问题的。
坚持这个责任,另一种方法可能是将这个接口下移到一个子实体中。如果这对您的情况是可能的,至少依赖关系仅限于需要它的场景。

+0

感谢您的回答,并对已故的回复感到抱歉。在这个项目中,没有服务层。 MVC项目直接访问域表面,使用工厂和门面模式。 IConsumeHttp依赖不在域实体上,它在另一个域类上。最终,元数据存储在域实体属性中,但它不是执行HTTP查找的实体。另外,当我说“缓存”时,我并不是指使用内存中的缓存。我的意思是XML内容存储在实体中,并使用元数据URL定期刷新。 – danludwig 2012-04-02 20:17:03

相关问题