8

我正在开发一个 .Net Web Forms 项目结构,我决定使用 Unity 作为应用程序的 DI 框架。

Asp.Net 中的 MSDN-Resolving指出,为了在我的项目中注入依赖项,我需要构建DI 容器之外创建的初始对象。话虽如此,我们来到了这个问题。

  1. 属性注释例如[Dependency]是扩展类的Attribute类。为了使用它们,必须在声明类中包含另一个命名空间,从而使我们的类依赖于Microsoft.Practices.Unity.DependencyAttribute该类。所以现在,即使我们的类可能不知道它使用的 IMyInterface 的实现,它也必须知道 Dependency 类的具体实现?我在这里想念什么?如果我们要更改 DI 框架,我们将需要删除整个项目中的所有注释。

  2. 有没有办法避免容器外部的这种声明(配置文件或其他东西)?

编辑 --> 代码在这里

/*This is the abstract base class where I want the dependency injection to occur*/
public abstract class BasePage : System.Web.UI.Page 
{
    private IMyService _dtService;   
    public IMyService DtService
    {
        get { return _dtService; }
        set { _dtService = value; }
    }
}

后面的 Default.aspx 代码

public partial class _Default : BasePage
{

    public _Default( )
    {

    }

    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            DataClass dt = DtService.GetDataById(2);
            lblWhatever.Text = dt.Description;
        }
    }
}

背后的全球代码

public class Global : System.Web.HttpApplication
{
   void Application_Start(object sender, EventArgs e)
    {
        IUnityContainer myContainer = HttpContext.Current.Application.GetDIContainer();
        myContainer.RegisterType<IMyService,MyServiceClient>(new 
                     InjectionConstructor("MyServiceWsEndpoint"));
        // I have tried this with BasePage too
        myContainer.RegisterType<_Default>(new InjectionProperty("DtService"));

    }
}

和模块

public class UnityHttpModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.PreRequestHandlerExecute += OnPreRequestHandlerExecute;
    }

    public void Dispose() { }

    private void OnPreRequestHandlerExecute(object sender, EventArgs e)
    {
        IHttpHandler currentHandler = HttpContext.Current.Handler;
        /*This does not work*/
HttpApplicationStateExtensions.GetDIContainer(HttpContext.Current.Application).BuildUp(
                          currentHandler.GetType(), currentHandler);
        /* While this works*/
HttpApplicationStateExtensions.GetDIContainer(HttpContext.Current.Application).BuildUp<_Default>((_Default)currentHandler);

        var currentPage = HttpContext.Current.Handler as Page;
        if (currentPage != null)
        {
            currentPage.InitComplete += OnPageInitComplete;
        }
    }
}

每次都会到达模块内部的代码。当我使用[Dependency]属性时,行确实有效。

4

1 回答 1

5

是的,使用 Dependency 属性的代码将实现与容器紧密耦合。

有几种方法可以确定要注入的属性:

  • 属性
  • XML 配置
  • 编程配置
  • 自定义容器扩展

绕过属性使用的一种方法是注册所有页面并以编程方式指定要注入的属性并根据需要提供覆盖BuildUp

IUnityContainer container = new UnityContainer();

// Assume we have a logger we are injecting
container.RegisterType<ILogger, Logger>(new ContainerControlledLifetimeManager());

// Register the Dependency Properties for the Page 'MyPage'.
// Property names on MyPage are "Logger"
container.RegisterType<MyPage>(new InjectionProperty("Logger"));

// ...later

IHttpHandler currentHandler = HttpContext.Current.Handler;

// Perform Property Injection.  
// Logger will be injected from the existing container registration.  
container.BuildUp(currentHandler.GetType(), currentHandler);
于 2013-07-15T16:16:05.607 回答