最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C# Autofac的具體使用

 更新時間:2024年08月26日 10:11:21   作者:alxiao  
Autofac是.NET領域最為流行的IoC框架之一,本文主要介紹了C# Autofac的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、為什么使用Autofac?

Autofac是.NET領域最為流行的IoC框架之一,傳說是速度最快的一個。

1.1、性能

有人專門做了測試:

在這里插入圖片描述

在這里插入圖片描述

1.2、優(yōu)點

1)與C#語言聯(lián)系很緊密。C#里的很多編程方式都可以為Autofac使用,例如可以使用Lambda表達式注冊組件。
2)較低的學習曲線。學習它非常的簡單,只要你理解了IoC和DI的概念以及在何時需要使用它們。
3)支持JSON/XML配置。
4)自動裝配。
5)與Asp.Net MVC集成。
6)微軟的Orchad開源程序使用的就是Autofac,可以看出它的方便和強大。

1.3、資源

二、數(shù)據(jù)準備

2.1、新建項目(例)

項目名稱項目說明輸出類型引用項目(簡寫)
AlXiao.IService接口類庫
AlXiao.Service接口實現(xiàn)類庫IService
AlXiao.AdminWebApi客戶端.NETWebApiIService、Service

IService下的接口類:

namespace AlXiao.IService
{
    public interface IAccountService
    {
        /// <summary>
        /// 后臺程序登陸
        /// </summary>
        /// <param name="UserRequest">后臺用戶信息</param>
        /// <returns></returns>
        Task<ResponseResult> LoginByWeb(tb_adminuser_request UserRequest);
    }
}

Service下的接口實現(xiàn)類:

namespace AlXiao.Service
{
    public class AccountService: IAccountService
    {
        /// <summary>
        /// 后臺程序登陸
        /// </summary>
        /// <param name="UserRequest">后臺用戶信息</param>
        /// <returns></returns>
        public async Task<ResponseResult> LoginByWeb(tb_adminuser_request UserRequest)
        {
            try
            {
              //自己寫登錄功能
            }
            catch (Exception ex)
            {
              
            }
        }
    }
}
namespace AlXiao.Service
{
    public class AccountService2: IAccountService
    {
        /// <summary>
        /// 后臺程序登陸
        /// </summary>
        /// <param name="UserRequest">后臺用戶信息</param>
        /// <returns></returns>
        public async Task<ResponseResult> LoginByWeb(tb_adminuser_request UserRequest)
        {
            try
            {
              //自己寫登錄功能
            }
            catch (Exception ex)
            {
              
            }
        }
    }
}

2.2、Autofac安裝

Client項目右鍵->管理 NuGet 程序包->Autofac

在這里插入圖片描述

三、IoC-注冊

3.1、類型注冊

a)類型注冊:使用RegisterType進行注冊

/注冊Autofac組件
ContainerBuilder builder = new ContainerBuilder;
//注冊實現(xiàn)類AccountService,當我們請求IAccountService接口的時候,返回的是類Student的對象。
builder.RegisterType<AccountService>.As<IAccountService> ;
//上面這句也可改成下面這句,這樣請求AccountService實現(xiàn)了的任何接口的時候,都會返回AccountService對象。
//builder.RegisterType<AccountService>.AsImplementedInterfaces();
IContainer container = builder.Build;
//請求IAccountService接口
IAccountService baseAccount= container.Resolve<IAccountService> ;
baseAccount.LoginByWeb(model);

b)類型注冊(別名):假如一個接口有多個實現(xiàn)類,可以在注冊時起別名。

ContainerBuilder builder = newContainerBuilder;
builder.RegisterType <AccountService>.Named<IAccountService>( "S1");
builder.RegisterType <AccountService2>.Named<IAccountService>( "S2");
IContainer container = builder.Build;
var s1= container.ResolveNamed<IAccountService >( "S1");
s1.LoginByWeb(model);
var s2 = container.ResolveNamed<IAccountService >( "S2");
s2.LoginByWeb(model);

c)類型注冊(枚舉):假如一個接口有多個實現(xiàn)類,也可以使用枚舉的方式注冊。

public enum ServiceType
{
AccountService,
AccountService2
}
ContainerBuilder builder = new ContainerBuilder;
builder.RegisterType <AccountService>.Keyed<IAccountService> (ServiceType.AccountService);
builder.RegisterType <AccountService2>.Keyed<IAccountService> (ServiceType.AccountService2);
IContainer container = builder.Build;
var s1= container.ResolveKeyed<IAccountService> (ServiceType.AccountService);
s1.LoginByWeb(model);
var s2= container.ResolveKeyed<IAccountService> (ServiceType.AccountService2);
s2.LoginByWeb(model);

3.2、實例注冊

ContainerBuilder builder = newContainerBuilder;
builder.RegisterInstance <IAccountService>( new AccountService);
IContainer container = builder.Build;
IAccountService baseAccount= container.Resolve<IAccountService> ;
baseAccount.LoginByWeb(model);

3.3、Lambda注冊

a)Lambda注冊

ContainerBuilder builder = newContainerBuilder;
builder.Register(c => new AccountService).As<IAccountService> ;
IContainer container = builder.Build;
IAccountService baseAccount= container.Resolve<IAccountService> ;
baseAccount.LoginByWeb(model);

b)Lambda注冊(NamedParameter)

ContainerBuilder builder = newContainerBuilder;
builder.Register<IAccountService>((c, p) =>
{
  vartype = p.Named<string>("type");
  if (type == "S1")
   {
     return new AccountService;
     }
  else
   {
     return new AccountService2;
   }
}).As<IAccountService>;
IContainer container = builder.Build;
var s1= container.Resolve<IAccountService>(newNamedParameter("type", "S1"));
s1.LoginByWeb(model);

3.4、程序集注冊

如果有很多接口及實現(xiàn)類,假如覺得這種一一注冊很麻煩的話,可以一次性全部注冊,當然也可以加篩選條件。

ContainerBuilder builder = newContainerBuilder;
Assembly assembly = Assembly.Load( "AlXiao.IService"); //實現(xiàn)類所在的程序集名稱
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces; //常用
//builder.RegisterAssemblyTypes(assembly).Where(t=>t.Name.StartsWith("Service")).AsImplementedInterfaces; //帶篩選
//builder.RegisterAssemblyTypes(assembly).Except<School>.AsImplementedInterfaces; //帶篩選
IContainer container = builder.Build;
//單實現(xiàn)類的用法
IAccountService baseAccount= container.Resolve<IAccountService> ;
baseAccount.LoginByWeb(model);
//多實現(xiàn)類的用法
IEnumerable<IAccountService> list= container.Resolve<IEnumerable<IAccountService>> ;
foreach( var item in list)
{
item.LoginByWeb(model);
}

3.5、泛型注冊

ContainerBuilder builder = new ContainerBuilder;
builder.RegisterGeneric(typeof(List<>)).As( typeof(IList<> ));
IContainer container = builder.Build;
IList <string> list = container.Resolve<IList<string>>; 

3.6、默認注冊

ContainerBuilder builder = new ContainerBuilder;
//對于同一個接口,后面注冊的實現(xiàn)會覆蓋之前的實現(xiàn)。
//如果不想覆蓋的話,可以用PreserveExistingDefaults,這樣會保留原來注冊的實現(xiàn)。
builder.RegisterType<AccountService>.As<IAccountService> ;
builder.RegisterType <AccountService1>.As<IAccountService>.PreserveExistingDefaults; //指定為非默認值
IContainer container = builder.Build;
var s1= container.Resolve<IAccountService> ;
s1.LoginByWeb(model);

四、IoC-注入

4.1、構造函數(shù)注入

ContainerBuilder builder = new ContainerBuilder;
builder.RegisterType <AccountService> ;
builder.RegisterType <AccountService1>.As<IAccountService> ;
IContainer container = builder.Build;
AccountService s1= container.Resolve<AccountService> ;
s1.LoginByWeb(model);

4.2、屬性注入

ContainerBuilder builder = new ContainerBuilder;
Assembly assembly = Assembly.Load( "AlXiao.IService"); //實現(xiàn)類所在的程序集名稱
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces.PropertiesAutowired; //常用
IContainer container = builder.Build;
IAccountService s1= container.Resolve<IAccountService> ;
s1.LoginByWeb(model);

五、IOC-事件

Autofac在組件生命周期的不同階段,共對應了5個事件,執(zhí)行順序如下所示:
1.OnRegistered->2.OnPreparing->3.OnActivating->4.OnActivated->5.OnRelease

ContainerBuilder builder = new ContainerBuilder;
builder.RegisterType <AccountService>.As<IAccountService>
.OnRegistered(e => Console.WriteLine( "OnRegistered:在注冊的時候調(diào)用"))
.OnPreparing(e => Console.WriteLine( "OnPreparing:在準備創(chuàng)建的時候調(diào)用"))
.OnActivating(e => Console.WriteLine( "OnActivating:在創(chuàng)建之前調(diào)用"))
//.OnActivating(e => e.ReplaceInstance(new Student("1000", "Test")))
.OnActivated(e => Console.WriteLine( "OnActivated:在創(chuàng)建之后調(diào)用"))
.OnRelease(e => Console.WriteLine( "OnRelease:在釋放占用的資源之前調(diào)用"));
using(IContainer container = builder.Build)
{
IAccountService s1= container.Resolve<IAccountService> ;
s1.LoginByWeb(model);
}

六、IoC-生命周期

6.1、Per Dependency

Per Dependency:為默認的生命周期,也被稱為"transient"或"factory",其實就是每次請求都創(chuàng)建一個新的對象。

ContainerBuilder builder = new ContainerBuilder;
Assembly assembly = Assembly.Load( "AlXiao.IService"); //實現(xiàn)類所在的程序集名稱
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces.PropertiesAutowired.InstancePerDependency; //常用
IContainer container = builder.Build;
IAccountService s1= container.Resolve<IAccountService> ;
IAccountService s2 = container.Resolve<IAccountService> ;
return s1.Equals(s2);

6.2、Single Instance

Single Instance:就是每次都用同一個對象。

ContainerBuilder builder = new ContainerBuilder;
Assembly assembly = Assembly.Load( "AlXiao.IService"); //實現(xiàn)類所在的程序集名稱
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces.PropertiesAutowired.SingleInstance; //常用
IContainer container = builder.Build;
IAccountService s1= container.Resolve<IAccountService> ;
IAccountService s2= container.Resolve<IAccountService> ;
return ReferenceEquals(s1, s2);

6.3、Per Lifetime Scope

Per Lifetime Scope:同一個Lifetime生成的對象是同一個實例。

ContainerBuilder builder = new ContainerBuilder;
builder.RegisterType <AccountService>.As<IAccountService> .InstancePerLifetimeScope;
IContainer container = builder.Build;
IAccountService s1= container.Resolve<IAccountService> ;
IAccountService s2 = container.Resolve<IAccountService> ;
Console.WriteLine(s1.Equals(s2));
using(ILifetimeScope lifetime = container.BeginLifetimeScope)
{
IAccountService s3 = lifetime.Resolve<IAccountService> ;
IAccountService s4 = lifetime.Resolve<IAccountService> ;
Console.WriteLine(s3.Equals(s4));
Console.WriteLine(s2.Equals(s3));
}

七、IoC-通過配置文件使用Autofac

7.1、組件安裝

Client項目右鍵->管理 NuGet 程序包->Autofac.Configuration及Microsoft.Extensions.Configuration.Xml。

在這里插入圖片描述

在這里插入圖片描述

7.2、配置文件

新建一個AutofacConfigIoC.xml文件,在其屬性的復制到輸出目錄項下選擇始終復制。

<?xml version="1.0" encoding="utf-8" ?>
<autofac defaultAssembly="AlXiao.IService">
<!--無注入-->
<components name="1001">
<type>AlXiao.IService.AccountService, AlXiao.IService </type>
<services name="0"type="AlXiao.IService.IAccountService"/>
<injectProperties>true </injectProperties>
</components>
<components name="1002">
<type>AlXiao.IService.AccountService, AlXiao.IService</type>
<services name="0"type="AlXiao.IService.IAccountService2"/>
<injectProperties>true </injectProperties>
</components>
<!--構造函數(shù)注入-->
<components name="2001">
<type>AlXiao.IService.AccountService, AlXiao.IService</type>
<services name="0"type="AlXiao.IService.AccountService, AlXiao.IService"/>
<injectProperties>true </injectProperties>
</components>
<!--屬性注入-->
<components name="3001">
<type>AlXiao.IService.AccountService, AlXiao.IService</type>
<services name="0"type="AlXiao.IService.IAccountService"/>
<injectProperties>true </injectProperties>
</components>
</autofac>

7.3、測試代碼

//加載配置

ContainerBuilder builder = new ContainerBuilder;
varconfig = new ConfigurationBuilder;
config.AddXmlFile( "AutofacConfigIoC.xml");
varmodule = newConfigurationModule(config.Build);
builder.RegisterModule(module);
IContainer container = builder.Build;
//無注入測試
IAccountService s = container.Resolve<IAccountService> ;
s.LoginByWeb(model);
//構造函數(shù)注入測試
AccountService s= container.Resolve<AccountService> ;
s.LoginByWeb(model);
//屬性注入測試
IAccountService s= container.Resolve<IAccountService> ;
s.LoginByWeb(model);

八、AOP

8.1、組件安裝

Client項目右鍵->管理 NuGet 程序包->Autofac.Extras.DynamicProxy。

在這里插入圖片描述

8.2、拉截器

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Castle.DynamicProxy;
namespace AlXiao.CommonCore.DTO
{
    ///<summary>
    ///攔截器:需實現(xiàn)IInterceptor接口。
    ///</summary>
    public class CallLogger : IInterceptor
    {
        private readonly TextWriter _output;
        public CallLogger(TextWriter output)
        {
            _output = output;
        }
        ///<summary>
        ///攔截方法:打印被攔截的方法--執(zhí)行前的名稱、參數(shù)以及執(zhí)行后的返回結果。
        ///</summary>
        ///<param name="invocation">被攔截方法的信息</param>
        public void Intercept(IInvocation invocation)
        {
            //空白行
            _output.WriteLine;
            //在下一個攔截器或目標方法處理之前的處理
            _output.WriteLine($ "調(diào)用方法:{invocation.Method.Name}");
            if (invocation.Arguments.Length > 0)
            {
                _output.WriteLine($ "參數(shù):{string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString).ToArray)}");
            }
            //調(diào)用下一個攔截器(若存在),直到最終的目標方法(Target Method)。
            invocation.Proceed;
            //獲取被代理方法的返回類型
            varreturnType = invocation.Method.ReturnType;
            //異步方法
            if (IsAsyncMethod(invocation.Method))
            {
                //Task:返回值是固定類型
                if (returnType != null && returnType == typeof(Task))
                {
                    //定義一個異步方法來等待目標方法返回的Task
                    asyncTask Continuation => await(Task)invocation.ReturnValue;
                    //Continuation中并沒有使用await,所以Continuation就如同步方法一樣是阻塞的。
                    invocation.ReturnValue = Continuation;
                }
                //Task<T>:返回值是泛型類型
                else
                {
                    //獲取被代理方法的返回類型
                    varreturnTypeT = invocation.Method.ReflectedType;
                    if (returnTypeT != null)
                    {
                        //獲取泛型參數(shù)集合,集合中的第一個元素等價于typeof(Class)。
                        varresultType = invocation.Method.ReturnType.GetGenericArguments[0];
                        //利用反射獲得等待返回值的異步方法
                        MethodInfo methodInfo = typeof(CallLogger).GetMethod("HandleAsync", BindingFlags.Public | BindingFlags.Instance);
                        //調(diào)用methodInfo類的MakeGenericMethod方法,用獲得的類型T(<resultType>)來重新構造HandleAsync方法。
                        varmi = methodInfo.MakeGenericMethod(resultType);
                        //Invoke:使用指定參數(shù)調(diào)用由當前實例表示的方法或構造函數(shù)。
                        invocation.ReturnValue = mi.Invoke(this, new[] { invocation.ReturnValue });
                    }
                }
                vartype = invocation.Method.ReturnType;
                varresultProperty = type.GetProperty("Result");
                if (resultProperty != null)
                    _output.WriteLine($ "方法結果:{resultProperty.GetValue(invocation.ReturnValue)}");
            }
            //同步方法
            else
            {
                if (returnType != null && returnType != typeof(void))
                    _output.WriteLine($ "方法結果:{invocation.ReturnValue}");
            }
        }
        ///<summary>
        ///判斷是否異步方法
        ///</summary>
        public static bool IsAsyncMethod(MethodInfo method)
        {
            return
            (
            method.ReturnType == typeof(Task) ||
            (method.ReturnType.IsGenericType && method.ReturnType.GetGenericTypeDefinition == typeof(Task<>))
            );
        }
        ///<summary>
        ///構造等待返回值的異步方法
        ///</summary>
        ///<typeparam name="T"></typeparam>
        ///<param name="task"></param>
        ///<returns></returns>
        public async Task<T> HandleAsync<T>(Task<T> task)
        {
            vart = awaittask;
            returnt;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Castle.DynamicProxy;
namespace AlXiao.CommonCore.DTO
{
    public class CallTester : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            Console.WriteLine("啥也不干");
            invocation.Proceed;
            Console.WriteLine("也不干啥");
        }
    }
}

8.3、測試代碼

注意:對于以類方式的注入,Autofac Interceptor要求類的方法必須為virtual方法。如AnimalWagging類的Wagging、WaggingAsync(string name)都加了virtual修飾符

ContainerBuilder builder = new ContainerBuilder;
//注冊攔截器
builder.Register(c => newCallLogger(Console.Out));
builder.Register(c => new CallTester);
//動態(tài)注入攔截器
//這里定義了兩個攔截器,注意它們的順序。
builder.RegisterType<Student>.As<IStudent>.InterceptedBy( typeof(CallLogger), typeof(CallTester)).EnableInterfaceInterceptors;
//這里定義了一個攔截器
builder.RegisterType<AnimalWagging>.InterceptedBy( typeof(CallLogger)).EnableClassInterceptors;
builder.RegisterType <Dog>.As<IAnimalBark> ;
IContainer container = builder.Build;
IStudent student = container.Resolve<IStudent> ;
student.Add( "1003", "Kobe");
AnimalWagging animal = container.Resolve<AnimalWagging> ;
animal.Wagging;
Task <string> task = animal.WaggingAsync( "哈士奇");
Console.WriteLine($ "{task.Result}");

到此這篇關于C# Autofac的具體使用的文章就介紹到這了,更多相關C# Autofac內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家! 

相關文章

  • C# ThreadPool之QueueUserWorkItem使用案例詳解

    C# ThreadPool之QueueUserWorkItem使用案例詳解

    這篇文章主要介紹了C# ThreadPool之QueueUserWorkItem使用案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C#基于正則去掉注釋的方法示例

    C#基于正則去掉注釋的方法示例

    這篇文章主要介紹了C#基于正則去掉注釋的方法,結合簡單實例形式分析了C#針對注釋符號的正則匹配相關操作技巧,需要的朋友可以參考下
    2017-05-05
  • 在C#中如何獲取程序集

    在C#中如何獲取程序集

    某一天我正在寫一些反射代碼,目的是遍歷所有的程序集來查找一個特定的接口,然后在Startup中調(diào)用其上的一個方法,這篇文章主要介紹了在C#中如何獲取程序集,需要的朋友可以參考下
    2024-03-03
  • 深入淺出掌握Unity ShaderLab語法基礎

    深入淺出掌握Unity ShaderLab語法基礎

    Unity中所有Shader文件都通過一種陳述性語言進行描述,稱為“ShaderLab”, 這篇文章主要介紹了Unity圖形學之ShaderLab入門基礎,需要的朋友可以參考下
    2023-05-05
  • 一篇文章徹底搞清楚c#中的委托與事件

    一篇文章徹底搞清楚c#中的委托與事件

    這篇文章主要給大家介紹了如何通過一篇文章徹底搞清楚c#中的委托與事件,文中通過示例代碼介紹的非常詳細,對大家學習或者使用c#具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-07-07
  • c# 實現(xiàn)的支付寶支付

    c# 實現(xiàn)的支付寶支付

    這篇文章主要介紹了c# 實現(xiàn)的支付寶支付的方法,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2021-01-01
  • C#異常處理中try和catch語句及finally語句的用法示例

    C#異常處理中try和catch語句及finally語句的用法示例

    這篇文章主要介紹了C#異常處理中try和catch語句及finally語句的用法示例,finally語句的使用涉及到了C#的垃圾回收特性,需要的朋友可以參考下
    2016-02-02
  • C#的3DES加密解密算法實例代碼

    C#的3DES加密解密算法實例代碼

    這篇文章主要介紹了C#的3DES加密解密算法實例代碼,有需要的朋友可以參考一下
    2013-11-11
  • C#正則函數(shù)用法實例【匹配、替換、提取】

    C#正則函數(shù)用法實例【匹配、替換、提取】

    這篇文章主要介紹了C#正則函數(shù)用法,結合實例形式分析了C#基于正則的匹配、替換、提取相關操作技巧,需要的朋友可以參考下
    2017-01-01
  • C#實現(xiàn)FTP上傳文件的方法

    C#實現(xiàn)FTP上傳文件的方法

    這篇文章介紹了C#實現(xiàn)FTP上傳文件的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04

最新評論

蒙自县| 五莲县| 仁布县| 高青县| 江源县| 鄂伦春自治旗| 宽城| 鹤山市| 苏尼特右旗| 宝清县| 冕宁县| 曲阜市| 九江县| 河池市| 旬邑县| 浦北县| 保德县| 扬州市| 山东省| 当阳市| 白朗县| 行唐县| 乌拉特中旗| 潞城市| 临城县| 唐海县| 扎鲁特旗| 云霄县| 舟山市| 芮城县| 陈巴尔虎旗| 苍溪县| 喀喇| 八宿县| 凉山| 土默特右旗| 灵丘县| 昭觉县| 庄河市| 延长县| 宝山区|