Winform窗体如何使用IOC容器呢?在nuget中添加Microsoft.Extensions.DependencyInjection
接着在Program类Main方法中添加一下代码
// 创建服务集
Build();
using (FmLogin fl = ServiceProvider.GetRequiredService<FmLogin>())
{
fl.ShowDialog();
if (fl.DialogResult == DialogResult.OK)
Application.Run(ServiceProvider.GetRequiredService<FmMain>());
}
在此类中继续补充以下代码
/// <summary>
/// 服务容器
/// </summary>
static IServiceCollection Services { get; set; }
/// <summary>
/// 服务管理者
/// </summary>
static IServiceProvider ServiceProvider { get; set; }
static void Build()
{
// 创建服务容器
Services = new ServiceCollection();
// 添加服务注册
ConfigureServices(Services);
// 创建服务管理者
ServiceProvider = Services.BuildServiceProvider();
}
/// <summary>
/// 注入服务
/// </summary>
/// <param name="services"></param>
static void ConfigureServices(IServiceCollection services)
{
// 注入日志
services.AddSingleton(typeof(ILogFactory<>),typeof(LogFactory<>));
// 注入窗体
RegisterForm();
// 注入IniHelper
services.AddScoped<IIniHelper, IniHelper>();
}
#region 注入窗体-开始
static void RegisterForm()
{
Type[]? types = Assembly.GetExecutingAssembly()?.GetExportedTypes();
if (types != null)
{
var descType = typeof(FormMarkAttribute);
var form = typeof(Form);
foreach (Type type in types)
{
// 类型是否为窗体,否则跳过,进入下一个循环
//if (type.GetTypeInfo != form)
// continue;
// 是否为自定义特性,否则跳过,进入下一个循环
if (!type.IsDefined(descType, false))
continue;
// 强制为自定义特性
FormMarkAttribute? attribute = type.GetCustomAttribute(descType, false) as FormMarkAttribute;
// 如果强制失败或者不需要注入的窗体跳过,进入下一个循环
if (attribute == null || !attribute.IsIOC)
continue;
// 域注入
Services.AddScoped(type);
Console.WriteLine($"注入:{attribute.FormType.Namespace}.{attribute.FormType.Name},{attribute.Describe}");
}
}
}
#endregion 注入窗体-结束
以后你的注入只需要在 static void ConfigureServices(IServiceCollection services)这个方法中注入就行了
全景图:
我把窗体也注入了,不过不是全部注入,是标记的并且是需要注入的,我们看FormMarkAttribute源码:
/// <summary>
/// Form窗体标记
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class FormMarkAttribute : Attribute
{
/// <summary>
/// 描述内容
/// </summary>
public string Describe { get; private set; }
/// <summary>
/// 是否运行注入,默认false
/// </summary>
public bool IsIOC { get; private set; }
/// <summary>
/// 窗体类型
/// </summary>
public Type FormType { get; private set; }
/// <summary>
/// 有参构造
/// </summary>
/// <param name="type">窗体反射类型</param>
public FormMarkAttribute(Type type)
{
this.FormType = type;
this.IsIOC = false;
this.Describe =String.Empty;
}
/// <summary>
/// 有参构造
/// </summary>
/// <param name="type">窗体反射类型</param>
/// <param name="describe">窗体描述</param>
public FormMarkAttribute(Type type, string describe)
{
this.Describe = describe;
this.IsIOC = false;
this.FormType = type;
}
/// <summary>
/// 有参构造
/// </summary>
/// <param name="type">窗体反射类型</param>
/// <param name="describe">是否需要注入</param>
public FormMarkAttribute(Type type, bool isIOC)
{
this.Describe = String.Empty;
this.IsIOC = isIOC;
this.FormType = type;
}
/// <summary>
/// 有参构造
/// </summary>
/// <param name="type">窗体反射类型</param>
/// <param name="describe">窗体描述</param>
/// <param name="isIOC">是否需要注入</param>
public FormMarkAttribute(Type type,string describe,bool isIOC)
{
this.Describe = describe;
this.IsIOC = isIOC;
this.FormType = type;
}
}
使用:
注意我的窗体继承的是FmCommonForm而不是Form,因为我可以在FmCommonForm里面写很多公共需要的方法、属性等;比如:全部窗体的icon图标,加载等待窗体等待。如下
需要源码的滴滴。。。