mie*_*sol 2 dependency-injection ioc-container asp.net-mvc-2
我一直在使用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);
}
...
}
Run Code Online (Sandbox Code Playgroud)
为了绑定QueryTypeContex到action参数,我们使用自定义模型绑定器从数据库中提取一些信息.一旦服务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);
}
...
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,所有这些方法QueryTypeContex作为参数更重要的是,它们QueryTypeContex在短暂的生命期间(一个Web请求)都获得了相同的实例 .所以我开始怀疑我是否可以重构这一点,以便每当许多服务类方法需要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);
}
...
}
Run Code Online (Sandbox Code Playgroud)
现在真正的问题是: 对于这种事情这是一个好主意还是违反了我应该坚持的一些设计原则?
为了注入QueryTypeContex实例,使用来自http请求的信息进行构建我考虑将QueryTypeId嵌入到uris中,以便它可以在服务器上的RouteData中使用.然后在构造控制器之前,我可以将其拉出来,QueryTypeContex为该请求构建,创建嵌套的IoC容器并将其注入容器中.然后,只要某个类需要QueryTypeContex执行其工作,它就会将其声明为构造函数参数.
任何你可以有意义地推动构造函数作为依赖的东西,你应该.与构造函数注入相关的依赖关系是实现细节,而方法参数是模型API的一部分.
通过构造函数重构依赖关系比修改API要容易得多,因此出于可维护性的原因,您应该尽可能少地使用方法参数.
| 归档时间: |
|
| 查看次数: |
134 次 |
| 最近记录: |