【发布时间】:2011-02-12 06:50:28
【问题描述】:
我使用 IoC 容器已经有一段时间了,但今天我发现代码中一遍又一遍地出现了一些“模式”。为了给您一些背景知识,我现在正在研究主要用于数据分析的 Web 应用程序。那里有一组功能,要求用户在一开始就选择我们所说的QueryTypeContex。选择此查询类型后,可能会采取其他步骤,但所有步骤均在此特定QueryTypeContex 中执行。在 gui 中,QueryTypeContex 拾取表示为使用其他控件打开新选项卡。
当用户使用给定的QueryTypeContex 工作时,对服务器的所有ajax 调用都包括QueryTypeId,它标识用户的选择并用于在服务器上构建QueryTypeContex,然后用于各种数据检索和操作。
我发现,我们使用 Ioc 容器构建的许多控制器(我们使用 asp.net mvc)都有一个共同点。有一个动作方法看起来有点像这样:
public class AttributeController : Controller
{
public AttributeController(IUsefulService usefulService)
{
_usefulservice = usefulService;
}
ActionResult GetAttributes(QueryTypeContex context)
{
var dataDto = _usefulService.Manipulate(context, currentUser);
return JSon(dataDto);
}
...
}
为了将QueryTypeContex 绑定到动作参数,我们使用自定义模型绑定器从数据库中提取一些信息。一旦服务获得QueryTypeContex 作为参数,它会将其或其属性传递给实例数据访问层的方法参数中的协作者。于是就有了一个像这样的工厂类
public interface IDateValueFactory
{
DateValue CurrentYear(QueryTypeContex context);
DateValue RollingMonth(int numberOfMonths, QueryTypeContex context);
DateValue RollingQuareter(int numberOfQuarters, QueryTypeContex context);
}
public class DateValueFactory : IDateValueFactory
{
public DateValueFactory(IDateValueDb dateValueDb)
{
_dateValueDb = dateValueDb;
}
public DateValue CurrentYear(QueryTypeContext context)
{
var currentYear = _dateValueDb.GetCurrentYear(context.Id);
return new DateValue(DateValueType.CurrentYear, currentYear, context);
}
public DateValue RollingMonth(int numberOfMonths, QueryTypeContex context)
{
return new DateValue(DateValueType.RollingMonth, numberOfMonths, context);
}
...
}
正如您所见,所有这些方法都将QueryTypeContex 作为参数,更重要的是它们在短暂的生命周期中都获得了完全相同的QueryTypeContex 实例(一个网络请求)。所以我开始怀疑我是否可以重构它,以便每当许多服务类方法需要QueryTypeContex 作为参数时,它将通过构造函数注入,而不是再次传递相同的值。例如:
public interface IDateValueFactory
{
DateValue CurrentYear();
DateValue RollingMonth(int numberOfMonths);
DateValue RollingQuareter(int numberOfQuarters);
}
public class DateValueFactory : IDateValueFactory
{
public DateValueFactory(IDateValueDb dateValueDb, QueryTypeContext context)
{
_dateValueDb = dateValueDb;
_context = context;
}
public DateValue CurrentYear()
{
var currentYear = _dateValueDb.GetCurrentYear(_context.Id);
return new DateValue(DateValueType.CurrentYear, currentYear, _context);
}
public DateValue RollingMonth(int numberOfMonths)
{
return new DateValue(DateValueType.RollingMonth, numberOfMonths, _context);
}
...
}
现在真正的问题是: 这是一个好主意,还是违反了我应该遵守的一些设计原则?
为了注入 QueryTypeContex 实例,使用来自 http 请求的信息构建,我考虑将 QueryTypeId 嵌入到 uri 中,以便它可以在服务器上的 RouteData 中使用。然后在构建控制器之前,我可以将其拉出,构建QueryTypeContex,为该请求创建嵌套的 IoC 容器并将其注入容器中。然后,每当某个类需要QueryTypeContex 来执行其工作时,它就会简单地将其声明为构造函数参数。
【问题讨论】:
-
您阅读指南了吗?
-
@PhoenixFF 哪个向导?
标签: asp.net-mvc-2 dependency-injection ioc-container