https://www.cnblogs.com/artech/p/net-core-di-01.html 大內老A的在.NET Core下對這些的介紹,有一系列文章 https://www.cnblogs.com/jesse2013/p/di-in-aspnetcore.html https://w ...
https://www.cnblogs.com/artech/p/net-core-di-01.html 大內老A的在.NET Core下對這些的介紹,有一系列文章
https://www.cnblogs.com/jesse2013/p/di-in-aspnetcore.html
https://www.cnblogs.com/artech/p/dependency-injection-in-asp-net-core.html
https://www.zybuluo.com/dasajia2lang/note/1481011
下麵開始
在上一篇的筆記中,在.NET Freamwork中,有一個第三方容器Unity,可以實現註入,但是在.NET Core裡面,有一個IServiceCollection,這個是.NET Core框架自帶的一個容器,和Unity很相似,都是個容器。
下麵我們新建一個控制台程式,在控制台程式中,對IServiceCollection的使用做介紹。
下麵代碼,是本次實例中需要註入的類型,需要用的倒是再點開來看吧
namespace Bingle.Core.Interface { public interface ITestServiceA { void Show(); } } namespace Bingle.Core.Service { public class TestServiceA : ITestServiceA { public void Show() { Console.WriteLine("A123456"); } } } namespace Bingle.Core.Interface { public interface ITestServiceB { void Show(); } } namespace Bingle.Core.Service { public class TestServiceB : ITestServiceB { public TestServiceB(ITestServiceA iTestService) { } public void Show() { Console.WriteLine($"This is TestServiceB B123456"); } } } namespace Bingle.Core.Interface { public interface ITestServiceC { void Show(); } } namespace Bingle.Core.Service { public class TestServiceC : ITestServiceC { public TestServiceC(ITestServiceB iTestServiceB) { } public void Show() { Console.WriteLine("C123456"); } } } namespace Bingle.Core.Interface { public interface ITestServiceD { void Show(); } } namespace Bingle.Core.Service { public class TestServiceD : ITestServiceD { public void Show() { Console.WriteLine("D123456"); } } }View Code
需要通過Nuget包,把IServiceCollection依賴的dll文件進入進來
Microsoft.Extensions.DependencyInjection
使用容器的三部曲:實例化一個容器、註冊、獲取服務
IServiceCollection container = new ServiceCollection(); // IServiceCollection container.AddTransient<ITestServiceA, TestServiceA>(); // 瞬時生命周期 每一次獲取的對象都是新的對象 container.AddSingleton<ITestServiceB, TestServiceB>(); // 單例生命周期 在容器中永遠只有當前這一個 container.AddScoped<ITestServiceC, TestServiceC>(); //當前請求作用域內 只有當前這個實例 container.AddSingleton<ITestServiceD>(new TestServiceD()); // 也是單例生命周期 ServiceProvider provider = container.BuildServiceProvider(); ITestServiceA testA = provider.GetService<ITestServiceA>(); ITestServiceA testA1 = provider.GetService<ITestServiceA>(); Console.WriteLine(object.ReferenceEquals(testA, testA1)); ITestServiceB testB = provider.GetService<ITestServiceB>(); ITestServiceB testB1 = provider.GetService<ITestServiceB>(); Console.WriteLine(object.ReferenceEquals(testB, testB1)); ITestServiceC testC = provider.GetService<ITestServiceC>(); ITestServiceC testC1 = provider.GetService<ITestServiceC>(); Console.WriteLine(object.ReferenceEquals(testC, testC1)); IServiceScope scope = provider.CreateScope(); ITestServiceC testc3 = provider.GetService<ITestServiceC>(); var testc4 = scope.ServiceProvider.GetService<ITestServiceC>(); Console.WriteLine(object.ReferenceEquals(testc3, testc4)); ITestServiceD testD = provider.GetService<ITestServiceD>(); ITestServiceD testD1 = provider.GetService<ITestServiceD>(); Console.WriteLine(object.ReferenceEquals(testD, testD1));
AutoFac也是個容器,下麵在Core中把AutoFac整合進來。
1、在Nuget中添加AutoFac
2、ConfigureService需要一個返回值,IServiceProvider(在.NET Core3.0中不需要替換)
3、實例化一個容器:
ContainerBuilder containerbuilder = new ContainerBuilder();
4、註冊服務,自定義一個類型,繼承Module,並重寫Load方法:
public class CustomAutofacModule:Module { /// <summary> /// 當前這Module 專用做服務註冊 /// </summary> /// <param name="builder"></param> protected override void Load(ContainerBuilder builder) { builder.RegisterType<TestServiceA>().As<ITestServiceA>().SingleInstance(); builder.RegisterType<TestServiceB>().As<ITestServiceB>().SingleInstance(); builder.RegisterType<TestServiceC>().As<ITestServiceC>().SingleInstance(); builder.RegisterType<TestServiceD>().As<ITestServiceD>().SingleInstance(); } }
在Startup.cs中的ConfigureServices()方法中加上一下代碼:
// services 預設的註冊服務,還需要處理控制器實例相關的的工作。 containerbuilder.Populate(services); // autofac 全權接管了之前這個Service的所有工作 containerbuilder.RegisterModule<CustomAutofacModule>(); IContainer container = containerbuilder.Build(); return new AutofacServiceProvider(container);
AutoFac支持AOP
AOP存在的意義,是在這個方法執行之前做什麼事,做完這個方法之後,又做什麼事。
1、安裝nuget包,DynamicProxy
2、自定義一個類,繼承IInterceptor介面
public class CustomAutofacAOP : IInterceptor { public void Intercept(IInvocation invocation) { Console.WriteLine($"method is {invocation.Method.Name}"); Console.WriteLine($"Arguments is {string.Join(';', invocation.Arguments)}"); invocation.Proceed();// 這裡表示繼續執行,就去執行之前應該執行的動作了 Console.WriteLine("**************"); } }
在之前的CustomAutofacModule也要稍作修改:
添加兩個測試類:
public interface IA { void Show(); } [Intercept(typeof(CustomAutofacAOP))] public class A : IA { public void Show() { Console.WriteLine("Cm"); } }
在一個控制器下,通過構造函數的方式來實現註入:
public class BingleController : Controller { private ILoggerFactory _factory = null; private ILogger<SecondController> _ilogger = null; private ITestServiceA _testServiceA = null; private ITestServiceB _testServiceB = null; private ITestServiceC _testServiceC = null; private ITestServiceD _testServiceD = null; private IA _a = null; public BingleController(ILoggerFactory factory, ILogger<SecondController> ilogger, ITestServiceA testServiceA, ITestServiceB testServiceB, ITestServiceC testServiceC, ITestServiceD testServiceD, IA a) { _factory = factory; _ilogger = ilogger; _testServiceA = testServiceA; _testServiceB = testServiceB; _testServiceC = testServiceC; _testServiceD = testServiceD; _a = a; } }