.net autofac Web Forms

autofac.web通常是对Page或用户/自定义控件做属性注入

public class Article:System.Web.UI.Page
{
       public IArticleService ArticleService{get;set;} 
        //PageLoad事件或其它代码地方直接调用ArticleService.Get....
}

1 安装autofac.web nuget方式

2 web.config中做配置

<configuration>
  <system.web>
    <httpModules>
      <!-- This section is used for IIS6 -->
      <add
        name="ContainerDisposal"
        type="Autofac.Integration.Web.ContainerDisposalModule, Autofac.Integration.Web"/>
      <add
        name="PropertyInjection"
        type="Autofac.Integration.Web.Forms.PropertyInjectionModule, Autofac.Integration.Web"/>
    </httpModules>
  </system.web>
  <system.webServer>
    <!-- This section is used for IIS7 -->
    <modules>
      <add
        name="ContainerDisposal"
        type="Autofac.Integration.Web.ContainerDisposalModule, Autofac.Integration.Web"
        preCondition="managedHandler"/>
      <add
        name="PropertyInjection"
        type="Autofac.Integration.Web.Forms.PropertyInjectionModule, Autofac.Integration.Web"
        preCondition="managedHandler"/>
    </modules>
  </system.webServer>
</configuration>

ContainerDisposalModule在页面释放请求结束时释放autofac创建的相关对象和autofacScope

PropertyInjectionModule 猜测这个是在页面创建后做依赖注入的。这里也可以用另一个类型UnsetPropertyInjectionModule,唯一的区别是若我们已经自己在构造函数中对依赖的属性赋值了,前者的方式是继续依赖注入,后者则不会。二者只能选其一

3 实现IContainerProviderAccessor

有时候我们想在代码中手动从容器中解析指定接口或类型,此时我们需要访问容器或生命周期(全局容器和生命周期请看相关文章),实现IContainerProviderAccessor的目的就是给我们提供一个访问容器或生命周期的一个点

autofac中通常让Global来实现这个接口

public class Global : HttpApplication, IContainerProviderAccessor
{
  // Provider that holds the application container.
  static IContainerProvider _containerProvider;

  // Instance property that will be used by Autofac HttpModules
  // to resolve and inject dependencies.
  public IContainerProvider ContainerProvider
  {
    get { return _containerProvider; }
  }

  protected void Application_Start(object sender, EventArgs e)
  {
    // Build up your application container and register your dependencies.
    var builder = new ContainerBuilder();
    builder.RegisterType<SomeDependency>();
    // ... continue registering dependencies...

    // Once you're done registering things, set the container
    // provider up with your registrations.
    _containerProvider = new ContainerProvider(builder.Build());
  }
}

 这样我们在代码中可以访问全局容器或生命周期了

var cpa = (IContainerProviderAccessor)HttpContext.Current.ApplicationInstance;
var cp = cpa.ContainerProvider;
cp.RequestLifetime....//当前请求生命周期
cp.ApplicationContainer //全局容器

4.1 自动注入

public class Article:System.Web.UI.Page
{
       public IArticleService ArticleService{get;set;} 
        //PageLoad事件或其它代码地方直接调用ArticleService.Get....
}

注意:若我们的用户控件也注册到了autofac,那么也会做依赖注入,但是若我们通过代码的方式或类似Repeater遍历创建的用户控件都不会做自动注入 ,此时可以参看下面的手动注入

4.2 手动注入

var cpa = (IContainerProviderAccessor)HttpContext.Current.ApplicationInstance;
var cp = cpa.ContainerProvider;
cp.RequestLifetime.InjectProperties(objectToSet);

4.3 选择性注入

有时候(比如讲autofac添加到现有的项目中),我们的有暴露的属性,但是有的我们需要注入 有的不需要注入 怎么办? 使用另一个注入HttpModule,配合Attribute来选择性注入

<configuration>
  <system.web>
    <httpModules>
      <!-- This section is used for IIS6 -->
      <add
        name="ContainerDisposal"
        type="Autofac.Integration.Web.ContainerDisposalModule, Autofac.Integration.Web"/>
      <add
        name="AttributedInjection"
        type="Autofac.Integration.Web.Forms.AttributedInjectionModule, Autofac.Integration.Web"/>
    </httpModules>
  </system.web>
  <system.webServer>
    <!-- This section is used for IIS7 -->
    <modules>
      <add
        name="ContainerDisposal"
        type="Autofac.Integration.Web.ContainerDisposalModule, Autofac.Integration.Web"
        preCondition="managedHandler"/>
      <add
        name="AttributedInjection"
        type="Autofac.Integration.Web.Forms.AttributedInjectionModule, Autofac.Integration.Web"
        preCondition="managedHandler"/>
    </modules>
  </system.webServer>
</configuration>

 此时所有页面公开的属性默认情况下不会被注入,除非添加InjectPropertiesAttribute或InjectUnsetPropertiesAttribute,用户控件也一样

4.4 不使用HttpModule方式注入

HttpModule的方式对所有页面、所用用户控件都会做注入。若我们只想对部分页面做注入,可以通过定义基类Page的方式实现

protected void Page_PreInit(object sender, EventArgs e)
{
  var cpa = (IContainerProviderAccessor)HttpContext.Current.ApplicationInstance;
  var cp = cpa.ContainerProvider;
  cp.RequestLifetime.InjectProperties(this);
}

4.5 自定义依赖注入Module

定义一个HttpModule实现Autofac.Integration.Web.DependencyInjectionModule

protected abstract IInjectionBehaviour GetInjectionBehaviourForHandlerType(Type handlerType);

The returned IInjectionBehaviour can be one of the predefined NoInjection, PropertyInjection, or UnsetPropertyInjection properties; or a custom implementation of the IInjectionBehaviour interface.

猜你喜欢

转载自www.cnblogs.com/jionsoft/p/8858870.html