.Net Core WPF中使用Autofac 依赖注入

2021-11-06  乐帮网

autofac wpf

首先建一个.Net Core WPF项目。这里是以.Net 5 下的WPF为例,使用的工具是VS 2019 ,同理适用于.Net Core 3 。

1、添加Nuget 包,添加Autofac,本人使用的都是最新稳定版。可以通过图形界面或者命令行

Install-Package Autofac -Version 6.3.0
Install-Package Autofac.Extensions.DependencyInjection 7.1.0
Install-Package Microsoft.Extensions.Hosting -Version 5.0.0
Install-Package Microsoft.Extensions.Hosting.Abstractions -Version 5.0.0

2、添加两个类来实现注入容器的替换VktServiceProvider 和 VktServiceProviderFactory

public class VktServiceProvider : IServiceProvider, ISupportRequiredService, IDisposable
    {

        private IContainer _container;

        private bool _disposed = false;

        public string name;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="container">IContainer</param>
        public VktServiceProvider(IContainer container)
        {
            this._container = container;
        }

        /// <summary>
        /// 获取服务的实现
        /// </summary>
        /// <param name="serviceType">serviceType</param>
        /// <returns>service object</returns>
        public object GetRequiredService(Type serviceType)
        {
            return this._container.Resolve(serviceType);
        }
        /// <summary>
        /// 获取服务的实现
        /// </summary>
        /// <param name="serviceType">serviceType</param>
        /// <returns>service object</returns>
        public object GetService(Type serviceType)
        {
            return this._container.ResolveOptional(serviceType);
        }
        /// <summary>
        /// 是否已经注册
        /// </summary>
        /// <param name="type">类型</param>
        /// <returns>true or false</returns>
        public bool IsRegistered(Type type)
        {
            return this._container.IsRegistered(type);
        }

        //public ILifetimeScope LifetimeScope => _lifetimeScope;

        /// <summary>
        /// 释放标识
        /// </summary>
        /// <param name="disposing">是否强制</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this._disposed)
            {
                if (disposing)
                {
                    this._container.Dispose();
                }

                this._disposed = true;
            }
        }
        /// <summary>
        /// 释放资源 
        /// </summary>
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

    }
 /// <summary>
    /// https://lebang2020.cn/details/211106ffdi3wri.html
    /// </summary>
    public class VktServiceProviderFactory : IServiceProviderFactory<ContainerBuilder>
    {
        private readonly Action<ContainerBuilder> _configurationAction;
        private readonly ContainerBuildOptions _containerBuildOptions = ContainerBuildOptions.None;

        private VktServiceProvider _serviceProider;
        /// <summary>
        /// 提供服务类
        /// </summary>
        public VktServiceProvider ServiceProvider
        {
            get
            {
                return _serviceProider;
            }
        }

        /// <summary>
        /// 初始化一个 AutofacServiceProviderFactory 类型的工厂
        /// </summary>
        /// <param name="containerBuildOptions">容器的构建参数</param>
        /// <param name="configurationAction">回调</param>
        public VktServiceProviderFactory(
            ContainerBuildOptions containerBuildOptions,
            Action<ContainerBuilder> configurationAction = null)
            : this(configurationAction) =>
            _containerBuildOptions = containerBuildOptions;

        /// <summary>
        /// 初始化一个 AutofacServiceProviderFactory 类型的工厂
        /// </summary>
        /// <param name="configurationAction">回调</param>
        public VktServiceProviderFactory(Action<ContainerBuilder> configurationAction = null) =>
            _configurationAction = configurationAction ?? (builder => { });



        public ContainerBuilder CreateBuilder(IServiceCollection services)
        {
            var builder = new ContainerBuilder();
           builder.RegisterModule<AutofacModule>();
            builder.Populate(services);

            _configurationAction(builder);

            return builder;
        }
        /// <summary>
        /// 使用容器创建
        /// </summary>
        /// <param name="containerBuilder">容器构建</param>
        /// <returns>IServiceProvider</returns>
        public IServiceProvider CreateServiceProvider(ContainerBuilder containerBuilder)
        {
            if (containerBuilder == null) throw new ArgumentNullException(nameof(containerBuilder));

            var container = containerBuilder.Build(_containerBuildOptions);
            _serviceProider = new VktServiceProvider(container);
            return _serviceProider;
        }
    }

3、添加测试服务接口和实现类和注册类如下

public class AutofacModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            var serviceTypesInAssembly = typeof(MainWindow).Assembly.GetExportedTypes().Where(type => type.FullName.EndsWith("Service")).ToArray();
            builder.RegisterTypes(serviceTypesInAssembly).AsImplementedInterfaces();
        }
    }

public interface ITestService
    {
        string SayHello();
    }

 public class TestService : ITestService
    {
        public string SayHello()
        {
            return "Hello";
        }
    }

4、修改项目中的App.xaml文件,去掉 StartupUri="MainWindow.xaml"

5、修改类 App.xaml.cs,如下:

  /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
   public partial class App : Application
    {
        public IConfiguration Configuration { get; private set; }

        public VktServiceProviderFactory ServiceProviderFactory { get; private set; }

        protected override void OnStartup(StartupEventArgs e)
        {
            ServiceProviderFactory = new VktServiceProviderFactory();
            var host = CreateHostBuilder().Build();
            var serviceProvider = host.Services;

            var mainWindow = serviceProvider.GetRequiredService<MainWindow>();
            mainWindow.Show();
        }



        private IHostBuilder CreateHostBuilder() =>
           Host.CreateDefaultBuilder().UseServiceProviderFactory(ServiceProviderFactory)
               .ConfigureHostConfiguration(config =>
               {
                   Configuration = config.Build();
               }).ConfigureServices(services=>
               {
                   services.AddTransient(typeof(MainWindow));
               });



    }

6、正常在类中使用注入示例如下:

 private readonly ITestService _testService;


        public MainWindow(ITestService testService)
        {
            _testService = testService;
            InitializeComponent();
        }

最终运行程序发现_testService被正常的注入进来了,一切工作正常,以后的注入扩展都在AutofacModule类中。

提供源码下载:链接:https://pan.baidu.com/s/1tGH9nsrWdU9bohYdp1mzkw 

.Net Core WPF中使用Autofac 依赖注入 - 乐帮网 (lebang2020.cn)

公众号二维码

关注我的微信公众号
在公众号里留言交流
投稿邮箱:1052839972@qq.com

庭院深深深几许?杨柳堆烟,帘幕无重数。
玉勒雕鞍游冶处,楼高不见章台路。
雨横风狂三月暮。门掩黄昏,无计留春住。
泪眼问花花不语,乱红飞过秋千去。

欧阳修

付款二维码

如果感觉对您有帮助
欢迎向作者提供捐赠
这将是创作的最大动力