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
庭院深深深几许?杨柳堆烟,帘幕无重数。
玉勒雕鞍游冶处,楼高不见章台路。
雨横风狂三月暮。门掩黄昏,无计留春住。
泪眼问花花不语,乱红飞过秋千去。
如果感觉对您有帮助
欢迎向作者提供捐赠
这将是创作的最大动力