(与这个问题相关的是,EF4:为什么启用延迟加载时必须启用代理创建?).
我对DI还不熟悉,请容忍我的问题。我知道容器负责实例化所有已注册的类型,但它需要引用解决方案中所有DLL及其引用。
如果我没有使用DI容器,在我的MVC3应用程序中,我就不必引用EntityFramework库,只需引用业务层,业务层将引用我的数据访问/存储库层。
我知道最终所有DLL都包含在bin文件夹中,但我的问题是必须通过在VS中“添加引用”来显式引用它,以便能够发布包含所有必要文件的WAP。
(与这个问题相关的是,EF4:为什么启用延迟加载时必须启用代理创建?).
我对DI还不熟悉,请容忍我的问题。我知道容器负责实例化所有已注册的类型,但它需要引用解决方案中所有DLL及其引用。
如果我没有使用DI容器,在我的MVC3应用程序中,我就不必引用EntityFramework库,只需引用业务层,业务层将引用我的数据访问/存储库层。
我知道最终所有DLL都包含在bin文件夹中,但我的问题是必须通过在VS中“添加引用”来显式引用它,以便能够发布包含所有必要文件的WAP。
正如绿色所示,现在可以重用Library C而不带来任何不必要的依赖关系。
然而,使用许多DI容器时,您不必添加对所有所需库的硬引用。相反,您可以使用延迟绑定,以约定为基础的程序集扫描(首选)或XML配置的形式。
但是,当您这样做时,必须记住将程序集复制到应用程序的bin文件夹中,因为这不再自动发生。个人而言,我很少觉得值得那么额外的努力。
这个答案的更详细版本可以在我的书Dependency Injection, Principles, Practices, Patterns的this excerpt中找到。
IEnumerable<T>
或IObserver<T>
作为依赖项。它们在BCL中已经定义,因此对所有消费者和实现者都自动可用。 - Mark Seemannpublic class DependencyRegistrarModule : IHttpModule
{
private static bool _dependenciesRegistered;
private static readonly object Lock = new object();
public void Init(HttpApplication context)
{
context.BeginRequest += (sender, args) => EnsureDependenciesRegistered();
}
public void Dispose() { }
private static void EnsureDependenciesRegistered()
{
if (!_dependenciesRegistered)
{
lock (Lock)
{
if (!_dependenciesRegistered)
{
ObjectFactory.ResetDefaults();
// Register all you dependencies here
ObjectFactory.Initialize(x => x.AddRegistry(new DependencyRegistry()));
new InitiailizeDefaultFactories().Configure();
_dependenciesRegistered = true;
}
}
}
}
}
public class InitiailizeDefaultFactories
{
public void Configure()
{
StructureMapControllerFactory.GetController = type => ObjectFactory.GetInstance(type);
...
}
}
DefaultControllerFactory不直接使用IoC容器,而是委托给IoC容器方法。
public class StructureMapControllerFactory : DefaultControllerFactory
{
public static Func<Type, object> GetController = type =>
{
throw new InvalidOperationException("The dependency callback for the StructureMapControllerFactory is not configured!");
};
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
return base.GetControllerInstance(requestContext, controllerType);
}
return GetController(controllerType) as Controller;
}
}
GetController
委托在 StructureMap 注册表中设置(在 Windsor 中应该是一个 Installer)。