Joh*_*esH 22 asp.net-mvc dependency-injection inversion-of-control unity-container
如果您不知道我在说什么,请查看教程并尝试自己添加依赖注入,或者尝试一下我对问题的解释.
注意:此问题不在ASP.NET原始教程的范围内.本教程仅建议使用的模式是依赖注入友好的.
问题基本上是Controller,ModelStateWrapper和ContactManagerService之间存在依赖循环.
所以依赖循环是这样的:Controller> Service> ModelStateWrapper> Controller
如果您尝试向此添加依赖项注入,它将失败.所以我的问题是; 我该怎么办呢?其他人已经发布了这个问题,但答案很少,不同,所有看起来都有点"黑客".
我目前的解决方案是从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...
}
Run Code Online (Sandbox Code Playgroud)
使用此构造,我可以像这样配置我的Unity容器:
public static void ConfigureUnityContainer()
{
IUnityContainer container = new UnityContainer();
// Registrations
container.RegisterTypeInHttpRequestLifetime<IContactRepository, EntityContactRepository>();
container.RegisterTypeInHttpRequestLifetime<IContactService, ContactService>();
ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这意味着服务上的"Initialize"方法必须由控制器构造函数手动调用.有没有更好的办法?也许我在我的统一配置中以某种方式包含IValidationDictionary?我应该切换到另一个DI容器吗?我错过了什么吗?
Mar*_*ann 11
作为一般考虑,循环依赖表示设计缺陷 - 我想我可以安全地说这个,因为你不是代码的原作者:)
我不认为Initialize方法是一个很好的解决方案.除非您正在处理加载项方案(您不是),否则Method Injection不是正确的解决方案.你几乎已经想到了这一点,因为你发现你需要手动调用它是不能令人满意的,因为你的DI容器不能.
除非我完全弄错了,否则在调用Action方法之前,ContactController不需要IValidationDictionary实例?
如果这是真的,最简单的解决方案可能是定义IValidationDictionaryFactory接口并使ContactController构造函数获取此接口的实例.
这个接口可以像这样定义:
public interface IValidationDictionaryFactory
{
IValidationDictionary Create(Controller controller);
}
Run Code Online (Sandbox Code Playgroud)
控制器上需要IValidationDictionary实例的任何Action方法都可以调用Create方法来获取实例.
默认实现看起来像这样:
public class DefaultValidationDictionaryFactory : IValidationDictionaryFactory
{
public IValidationDictionary Create(Controller controller)
{
return controller.ModelState;
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5500 次 |
最近记录: |