WPF多数类概念性注册加自动扫描

在java中springboot的配置应用了自动扫描

@ComponentScan(value = {"com.example", "com.fox"})

而对于Asp.Net Core 可以使用Scrutor

    static void Main(string[] args)
    {
        var collection = new ServiceCollection();
        collection.Scan(action => 
        	action.FromAssemblyOf<IScanAssemblyMarker>()
        	
            .AddClasses(@class => @class.Where(t => t.Name.EndsWith("Service")))
            .UsingRegistrationStrategy(RegistrationStrategy.Throw)
            .AsMatchingInterface()
            .WithScopedLifetime()
            
            .AddClasses(@class => @class.Where(t => t.Name.EndsWith("Repository")))
            .UsingRegistrationStrategy(RegistrationStrategy.Throw)
            .AsMatchingInterface()
            .WithSingletonLifetime());
    
        foreach (var item in collection)
        {
            var log = $"Service: {item.ServiceType.FullName} Lifetime: {item.Lifetime}\nInstance: {item.ImplementationType?.FullName}\n";
            Console.WriteLine(log);
        }
    }

唯独WPF没有,悲催,所以他时常是这样的

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
      containerRegistry.RegisterScoped<IHeaderItemRepository, HeaderItemRepository>();
      containerRegistry.RegisterScoped<IHeaderService, HeaderItemService>();

      containerRegistry.RegisterForNavigation<GeneratorView, GeneratorViewModel>();
}

我这个都算写的少了,多的可长达20行也是可以的,虽然Prism内置了Module,可以模块化分布写
但是我们可以自己实现一个扫描器
只需要用到反射
众所周知,看代码

public static void GetParentInfo()
{
    Type type = typeof(SubClasses);
    Type baseType = type.BaseType;
    Console.WriteLine("父类"+baseType.Name);         //获取父类

    Type[] interfaces= type.GetInterfaces();
    foreach (Type iface in interfaces) 
    {
        Console.WriteLine("父类接口"+iface.Name);       //获取所有父类接口
    }
}

public static void GetSubClassesInfo() 
{
    var typesImplementingC = Assembly.GetExecutingAssembly().GetTypes()
    .Where(t => typeof(IParent).IsAssignableFrom(t) && !t.IsInterface);

    foreach (var type in typesImplementingC)
    {
        Console.WriteLine("子类: " + type.Name);
        Console.WriteLine("平类:"+type.BaseType.Name);
    }
}

我这里提供两点思路,1、扫描程序集,2、自定义接口去注册

 public interface IPrismComponent
 {

 }
public void Register()
{
    var assembly = Assembly.GetExecutingAssembly(); // 获取当前执行的程序集
    var types = assembly.GetTypes()
        .Where(myType => myType.IsClass && !myType.IsAbstract && typeof(IPrismComponent).IsAssignableFrom(myType)); // 找到所有实现了IPrismComponent的非抽象类

    foreach (var type in types)
    {
        containerRegistry.RegisterScoped(typeof(IPrismComponent), type); // 将找到的类型注册为IPrismComponent的实现
    }
}

唯一有缺陷的地方就是Prism中对于注册仓储,注册服务,注册导航,用到的方法不一样,我暂时还没有想到好的办法,
唯一的想法就是这个类是Repository结尾,是Service结尾还是ViewModel结尾,然后给这些类都标注特性

[Register]
public class MainViewModel{}
[Register]
public class MainService{}
[Register]
public class MainRepository{}

不过这样一来就和Prism对View和ViewModel的注册思想是一样的,我也是吸取了它的思想,约定大于配置
接下来我们对不同结尾的类进行分布处理
使用特性,让这些类在实例化之前以不同的方式注册,
不管是单例注册,瞬时注册,作用域注册,UI导航注册

我们使用AOP去处理,
这样就不用写一长串的

 protected override void RegisterTypes(IContainerRegistry containerRegistry)
 {
 
 }

而又因为最新的WPF是可以内置js的,所以会前端的福利来了
不会的也没关系
在Asp.Net Core中是程序启动自动扫描appsetting.json的
WPF没有这个功能,除非使用WPF使用Furion框架,它里面内置了这个功能,
通常情况下,我们的json文件是这样的

{
  "SqlConnection": {
    "ConnectionMMsql": "server=.;uid=sa;pwd=xxx;database=xxx;Trusted_Connection=true;",
    "ConnectionMysql":
    "database = xxx; server = localhost; port = 3306; uid = xxx; pwd = xxx; "
  }
}

我们可以在这里配置,然后序列化对象,这样省去了写代码
这应该是最好的应用方式,我们在这里配置

"scaning":"true,xxx"

达到扫描某个程序集,并给true
只需要在程序启动打开这个json的序列化就行了

本文作者:孤沉

本文链接:https://www.cnblogs.com/guchen33/p/18062660

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   孤沉  阅读(36)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开