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图标,加载等待窗体等待。如下

需要源码的滴滴。。。 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐