【发布时间】:2009-09-21 06:40:54
【问题描述】:
如果您不知道我在说什么,请通过the tutorial 并尝试自己添加依赖注入,或者试试我对问题的解释。
注意:此问题不在 ASP.NET 原始教程的范围内。本教程仅建议使用的模式对依赖注入友好。
问题基本上是Controller、ModelStateWrapper和ContactManagerService之间存在依赖循环。
- ContactController 构造函数采用 IContactManagerService。
- ContactManagerService 构造函数采用 IContactManagerRepository (不重要) 和 IValidationDictionary (ModelStateWrapper 实现)。
- ModelStateWrapper 构造函数采用 ModelStateDictionary(它是控制器上称为“ModelState”的属性)。
所以依赖循环是这样的:Controller > Service > ModelStateWrapper > Controller
如果你尝试向它添加依赖注入,它将失败。所以我的问题是;我该怎么办?其他人已经发布了这个问题,但答案很少、不同,而且看起来都有点“hack-ish”。
我目前的解决方案是从 IService 构造函数中删除 IModelStateWrapper 并添加一个 Initialize 方法,如下所示:
public class ContactController : Controller
{
private readonly IContactService _contactService;
public ContactController(IContactService contactService)
{
_contactService = contactService;
contactService.Initialize(new ModelStateWrapper(ModelState));
}
//Class implementation...
}
public class ContactService : IContactService
{
private IValidationDictionary _validationDictionary;
private readonly IContactRepository _contactRepository;
public ContactService(IContactRepository contactRepository)
{
_contactRepository = contactRepository;
}
private void Initialize(IValidationDictionary validationDictionary)
{
if(validationDictionary == null)
throw new ArgumentNullException("validationDictionary");
_validationDictionary = validationDictionary;
}
//Class implementation...
}
public class ModelStateWrapper : IValidationDictionary
{
private readonly ModelStateDictionary _modelState;
public ModelStateWrapper(ModelStateDictionary modelState)
{
_modelState = modelState;
}
//Class implementation...
}
有了这个结构,我可以像这样配置我的统一容器:
public static void ConfigureUnityContainer()
{
IUnityContainer container = new UnityContainer();
// Registrations
container.RegisterTypeInHttpRequestLifetime<IContactRepository, EntityContactRepository>();
container.RegisterTypeInHttpRequestLifetime<IContactService, ContactService>();
ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
}
不幸的是,这意味着服务上的“Initialize”方法必须由控制器构造函数手动调用。有没有更好的办法?也许我以某种方式将 IValidationDictionary 包含在我的统一配置中?我应该切换到另一个 DI 容器吗?我错过了什么吗?
【问题讨论】:
-
我不得不承认我已经完成了 3 次本教程,但从未遇到过这个?是源代码中的问题还是手动遵循教程,如果是后者,您可能错过了一步?
-
这个问题超出了原始教程的范围,该教程仅暗示了依赖注入,但从未出现过展示它应该如何完成。我会澄清这个问题。
标签: asp.net-mvc dependency-injection inversion-of-control unity-container