zoukankan      html  css  js  c++  java
  • Unity与ASP.NET的集成(官方方法)

    最近有用到Unity与微软企业库与ASP.NET的集成,这样就可以将微软企业库作为一套解决方案,来搭建ASP.NET的项目框架,在很大程度上解决了一些常见的需要,如日志记录,异常处理等等。

    在网上搜索的时候,发现了一些解决方案,但是都不太满意,后来依稀记得Unity的动手实验里面有这么个内容。

    贴在这里,给有这个需要的广大群众和我自己留个记号,呵呵。

     

    Introduction

    In this lab, you will practice using Unity with an ASP.NET application. Because the creation of ASP.NET objects is managed by the ASP.NET infrastructure, the Unity container cannot be used to create them. Instead, the container will be used to apply injection to existing objects using the BuildUp method. For information about the BuildUp methods, see Using BuildUp to Wire Up Objects Not Created by the Container.

    To begin, open the StocksTicker.sln file located in the Labs\Lab05\begin\StocksTicker folder.

    Reviewing the Application

    The application is a simplified ASP.NET version of the stocks ticker application used throughout these labs. Just like with the Windows Forms version of the application, stock symbols can be subscribed to, and the latest updates on the stocks are displayed in a table, as illustrated in Figure 6.

    image

    Figure 6
    Stocks Ticker application

    Task 1: Integrating with ASP.NET

    In this task, the application will be updated to use a single, application-wide container to perform injection on its Web forms before they process requests.

    Adding References to the Required Assemblies

    To add references to the required assemblies

    1. Add references to the Microsoft.Practices.Unity, Microsoft.Practices.Unity.Configuration and Microsoft.Practices.ObjectBuilder2 assemblies from the Unity bin folder.
    2. Add a reference to the .NET Framework's System.Configuration assembly.

    Updating the Default Page to Use Property Injection

    To update the default page to use property injection

    1. Open the Default.aspx.cs file. If it is not visible, expand the node for the Default.aspx file.
    2. Add a using directive for the Unity namespace.
      using Microsoft.Practices.Unity;
      
    3. Remove the initialization code from the Page_Load method, as shown in the following code.
      protected void Page_Load(object sender, EventArgs e)
      {
          this.stockQuoteService = new MoneyCentralStockQuoteService();
          if (!this.IsPostBack)
          {
              UpdateQuotes();
          } 
      }
      
    4. Add the Dependency attribute to the StockQuoteService, as shown in the following code.
      private IStockQuoteService stockQuoteService;
      [Dependency]
      public IStockQuoteService StockQuoteService
      {
          get { return stockQuoteService; }
          set { stockQuoteService = value; }
      }
      

      Note:

      Configuration files cannot be used in this case because the assembly name for the page class is not known in advance so assembly-qualified type names cannot be expressed.

    Adding a Global.asax File to Manage the Container

    The HttpApplication class is used to define common methods in an ASP.NET application, so the code to manage the Unity container will be added to a new Global.asax file. For information about HTTP application classes, see HttpApplication Class.

    To add a Global.asax file to manage the container

    1. Add a Global.asax file. Right-click the StocksTicker project node, point to Add, and then click New Item. Select the Global Application Class template, and then click Add, as shown in Figure 7.

      image  

      Figure 7
      Adding a new application class

    2. Add using statements for the required namespaces:
      using Microsoft.Practices.Unity;
      using Microsoft.Practices.Unity.Configuration;
      using System.Web.Configuration;
      using System.Web.UI;
      
    3. Add a constant named AppContainerKey with "application container" as its value:
      public class Global : System.Web.HttpApplication
      {
          private const string AppContainerKey = "application container";
      
          protected void Application_Start(object sender, EventArgs e)
          {
      
          }
      
    4. Add an ApplicationContainer property to store a Unity container in the application state using the key defined earlier.
      private IUnityContainer ApplicationContainer
      {
          get
          {
              return (IUnityContainer)this.Application[AppContainerKey];
          }
          set
          {
              this.Application[AppContainerKey] = value;
          }
      }
      

      Note:

      The container is stored in the application's shared state.

    5. Add the following method to set up a container using settings from the configuration file.
      private static void ConfigureContainer(
          IUnityContainer container,
          string containerName)
      {
          UnityConfigurationSection section
              = WebConfigurationManager.GetWebApplicationSection("unity")
                  as UnityConfigurationSection;
      
          if (section != null)
          {
              UnityContainerElement containerElement
                  = section.Containers[containerName];
              if (containerElement != null)
              {
                  containerElement.Configure(container);
              }
          }
      }
      
    6. Update the empty Application_Start method to create a Unity container, configure it with the information for the "application" container from the configuration file and set it as the value for the ApplicationContainer property.
      protected void Application_Start(object sender, EventArgs e)
      {
          IUnityContainer applicationContainer = new UnityContainer();
          ConfigureContainer(applicationContainer, "application");
      
          ApplicationContainer = applicationContainer;
      }
      
    7. Update the empty Application_End method to dispose the application's container.
      protected void Application_End(object sender, EventArgs e)
      {
          IUnityContainer applicationContainer = this.ApplicationContainer;
      
          if (applicationContainer != null)
          {
              applicationContainer.Dispose();
      
              this.ApplicationContainer = null;
          }
      }
      
    8. Add a method named Application_PreRequestHandlerExecute to intercept the ASP.NET execution pipeline and use the container to inject dependencies into the request handler if the handler is a Page.

      protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
      {
          Page handler = HttpContext.Current.Handler as Page;

          if (handler != null)
          {
              IUnityContainer container = ApplicationContainer;

              if (container != null)
              {
                  container.BuildUp(handler.GetType(), handler);
              }
          }
      }

    Adding Unity Configuration to the Web.config File

    The configuration in a Web.config file uses the same schema as in an App.config file.

    To add Unity configuration to the Web.config file

    1. Open the Web.config file.
    2. Add a declaration for the unity configuration section.
      <configSections>
        ...
        <section name="unity"
                 type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      </configSections>
      
    3. Add the unity section element.
        </system.diagnostics>
        <unity>
        </unity>
      </configuration>
      
    4. Add typeAlias elements for the types used throughout the labs.
      <unity>
        <typeAliases>
          <typeAlias
            alias="string"
            type="System.String, mscorlib" />
          <typeAlias
            alias="TraceSource"
            type="System.Diagnostics.TraceSource, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      
          <typeAlias
            alias="singleton"
            type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      
          <typeAlias
            alias="ILogger"
            type="StocksTicker.Loggers.ILogger, StocksTicker" />
          <typeAlias
            alias="TraceSourceLogger"
            type="StocksTicker.Loggers.TraceSourceLogger, StocksTicker" />
      
          <typeAlias
            alias="IStockQuoteService"
            type="StocksTicker.StockQuoteServices.IStockQuoteService, StocksTicker" />
          <typeAlias
            alias="MoneyCentralStockQuoteService"
            type="StocksTicker.StockQuoteServices.MoneyCentralStockQuoteService, StocksTicker" />
        </typeAliases>
      </unity>
      
    5. Add elements for the containers collection and a container with the name application.
        </typeAliases>
      
        <containers>
          <container name=”application”>
          </container>
        </containers>
      </unity>
      
    6. Add the types element.
      <container name="application">
        <types>
        </types>
      </container>
      
    7. Add a type element to map the IStockQuoteService interface to the MoneyCentralStockQuoteService class with a property element to inject the Logger property and define a singleton lifetime manager.

      <container name="application">
        <types>
          <type type="IStockQuoteService" mapTo="MoneyCentralStockQuoteService">
            <lifetime type="singleton"/>
            <typeConfig>
              <property name="Logger" propertyType="ILogger"/>
            </typeConfig>
          </type>
        </types>
      </container>

    8. Add a type element to map the ILogger interface to the TraceSourceLogger class, defining a singleton lifetime manager and injecting the "default" string in its constructor. This mapping is required to inject the Logger property on the MoneyCentralStockQuoteService instance.
      <container name="application">
        <types>
          <type type="ILogger" mapTo="TraceSourceLogger">
            <lifetime type="singleton"/>
            <typeConfig>
              <constructor>
                <param name="sourceName" parameterType="string">
                  <value value="default"/>
                </param>
              </constructor>
            </typeConfig>
          </type>
          <type type="IStockQuoteService" mapTo="MoneyCentralStockQuoteService">
            <typeConfig>
              <property name="Logger" propertyType="ILogger"/>
            </typeConfig>
          </type>
        </types>
      </container>
      

    Running the Application

    To run the application

    1. Launch the application. Open two browser instances, as shown in Figure 8, and open the application's URL in them. Use the application for a while in both browsers, subscribing to different sets of symbols.

       image

      Figure 8
      Multiple instances of the application

    2. Close the browsers and stop the development server. To do this, right-click the image icon in the taskbar, and then click Stop.
    3. Open the trace.log file located in the StocksTicker folder. The contents at the bottom of the file should look like the following log, with messages indicating the processing of the different sets of requests and the final two entries indicating that the service and the logger were disposed.
      default Information: 0 : Parsed result for YHOO GM 
          DateTime=2009-02-23T18:15:25.4761924Z
      default Information: 0 : Retrieving quotes for BAC MSFT 
          DateTime=2009-02-23T18:15:29.1101924Z
      default Information: 0 : Received result for BAC MSFT 
          DateTime=2009-02-23T18:15:29.5251924Z
      default Information: 0 : Parsed result for BAC MSFT 
          DateTime=2009-02-23T18:15:29.5251924Z
      default Information: 0 : Shutting down service
          DateTime=2009-02-23T18:15:44.6961924Z
      default Information: 0 : Shutting down logger
          DateTime=2009-02-23T18:15:44.6971924Z
      

    Task 2: Using Per-Session Child Containers

    In this task, a more sophisticated container management strategy will be implemented: the application-wide container will hold services shared by all sessions, but other objects will be managed by a session-specific container. In this case, the service used to retrieve quotes will not be shared, but its lifetime will be managed. Of course, this approach works only when session state is enabled and stored InProc.

    Container hierarchies can be used to control the scope and lifetime of objects and to register different mappings in different context. In this task, a two-level hierarchy will be implemented. For information about container hierarchies, see Using Container Hierarchies.

    Updating the Global.asax File to Manage Per-Session Containers

    To update the Global.asax file to manage per-session containers

    1. Open the Global.asax file.
    2. Add a constant named SessionContainerKey with "session container" as its value:
      public class Global : System.Web.HttpApplication
      {
          private const string AppContainerKey = "application container";
          private const string SessionContainerKey = "session container";
      
    3. Add a SessionContainer property to store a Unity container in the application state using the key defined earlier.
      private IUnityContainer SessionContainer
      {
          get
          {
              return (IUnityContainer)this.Session[SessionContainerKey];
          }
          set
          {
              this.Session[SessionContainerKey] = value;
          }
      }
      
    4. Add a Session_Start method to create a child container of the application's container using the CreateChildContainer method, configure it with the information for the "session" container from the configuration file and set it as the value for the SessionContainer property.
      protected void Session_Start(object sender, EventArgs e)
      {
          IUnityContainer applicationContainer = this.ApplicationContainer;
      
          if (applicationContainer != null)
          {
              IUnityContainer sessionContainer 
                  = applicationContainer.CreateChildContainer();
              ConfigureContainer(sessionContainer, "session");
      
              this.SessionContainer = sessionContainer;
          }
      }
      
    5. Add a Session_End method to dispose the session's container.
      protected void Session_End(object sender, EventArgs e)
      {
          IUnityContainer sessionContainer = this.SessionContainer;
          if (sessionContainer != null)
          {
              sessionContainer.Dispose();
      
              this.SessionContainer = null;
          }
      }
      
    6. Update the Application_PreRequestHandlerExecute method to use the session container to BuildUp the request's handler.
      protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
      {
          Page handler = HttpContext.Current.Handler as Page;
      
          if (handler != null)
          {
              IUnityContainer container = SessionContainer;
      
              if (container != null)
              {
                  container.BuildUp(handler.GetType(), handler);
              }
          }
      }
      

    Updating the Unity Configuration with a Session Container

    To update the Unity configuration with a session container

    1. Open the Web.config file.
    2. Add a new container element with name session as a child of the containers element.
      <containers>
        <container name="application">
          ...
        </container>
      
        <container name="session">
          <types>
          </types>
        </container>
      </containers>
      
    3. Add a type element to map the IStockQuoteService interface to the MoneyCentralStockQuoteService class with a property element to inject the Logger property and define a singleton lifetime manager.
      <container name="session">
        <types>
          <type type="IStockQuoteService" mapTo="MoneyCentralStockQuoteService">
            <lifetime type="singleton"/>
            <typeConfig>
              <property name="Logger" propertyType="ILogger"/>
            </typeConfig>
          </type>
        </types>
      </container>
      
    4. Remove the type element mapping the IStockQuoteService interface from the types collection for the application container.
      <container name="application">
        <types>
          <type type="ILogger" mapTo="TraceSourceLogger">
            <lifetime type="singleton"/>
            <typeConfig>
              <constructor>
                <param name="sourceName" parameterType="string">
                  <value value="default"/>
                </param>
              </constructor>
            </typeConfig>
          </type>
          <type type="IStockQuoteService" mapTo="MoneyCentralStockQuoteService">
            <typeConfig>
              <property name="Logger" propertyType="ILogger"/>
            </typeConfig>
          </type>
        </types>
      </container>
      

    Running the Application

    To run the application

    1. Launch the application. Open two browser instances and open the application's URL in them. Use the application for a while in both browsers, subscribing to different sets of symbols.
    2. Close one of the browser instances and wait for 90 seconds. The session timeout interval is set to one minute in the configuration file, so this wait should be enough for the session to expire.
    3. Close the other browser instance, and then stop the development Web server.
    4. Open the trace.log file located in the StocksTicker folder. The contents at the bottom of the file should look like the following log, with entries for each of the service instances and for the shared logger.
      default Information: 0 : Retrieving quotes for MSFT BAC 
          DateTime=2009-02-23T19:06:45.7471924Z
      default Information: 0 : Received result for MSFT BAC 
          DateTime=2009-02-23T19:06:46.1491924Z
      default Information: 0 : Parsed result for MSFT BAC 
          DateTime=2009-02-23T19:06:46.1491924Z
      default Information: 0 : Shutting down service
          DateTime=2009-02-23T19:07:00.0781924Z
      default Information: 0 : Retrieving quotes for MSFT BAC 
          DateTime=2009-02-23T19:07:05.7731924Z
      default Information: 0 : Received result for MSFT BAC 
          DateTime=2009-02-23T19:07:06.1841924Z
      default Information: 0 : Parsed result for MSFT BAC 
          DateTime=2009-02-23T19:07:06.1841924Z
      default Information: 0 : Retrieving quotes for MSFT BAC 
          DateTime=2009-02-23T19:07:25.7691924Z
      default Information: 0 : Received result for MSFT BAC 
          DateTime=2009-02-23T19:07:26.1791924Z
      default Information: 0 : Parsed result for MSFT BAC 
          DateTime=2009-02-23T19:07:26.1791924Z
      default Information: 0 : Shutting down service
          DateTime=2009-02-23T19:07:44.2521924Z
      default Information: 0 : Shutting down logger
          DateTime=2009-02-23T19:07:44.2541924Z
      

    To verify you have completed the lab correctly, you can use the solution provided in the Labs\Lab05\end\StocksTicker folder.r.

    Footer image

    To give feedback, get assistance or download additional content please visit the Unity Application Block Community.

    Copyright © 2009 by Microsoft Corporation. All rights reserved.

  • 相关阅读:
    SpringMvc@RequestParam 来映射请求参数
    SpringMvc中@PathVariable注解简单的用法
    SpringMvc的学习之路
    平常的操作函数以及回调
    关于弹窗 取消 确定清空按钮的事件
    判断主表里子表不能添加相同的字段
    选择company回显appname
    树形菜单数据源
    .NET为什么要使用异步(async)编程?⭐⭐⭐⭐⭐
    通过HttpClient的方式去Curd数据⭐⭐⭐⭐
  • 原文地址:https://www.cnblogs.com/HCOONa/p/1590856.html
Copyright © 2011-2022 走看看