/// <summary> /// 根据Assembly扫描所有继承IEntityTypeConfiguration<T>的配置类 /// </summary> /// <param name="codeFirst"></param> /// <param name="assembly"></param> /// <param name="predicate"></param> /// <returns></returns> public static ICodeFirst ApplyConfigurationsFromAssembly(this ICodeFirst codeFirst, Assembly assembly, Func <Type, bool> predicate = null) { IEnumerable <TypeInfo> typeInfos = assembly.DefinedTypes.Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition); MethodInfo methodInfo = typeof(FreeSqlDbContextExtensions).Assembly.GetExtensionMethods(typeof(ICodeFirst)) .Single((e) => e.Name == "Entity" && e.ContainsGenericParameters); if (methodInfo == null) { return(codeFirst); } foreach (TypeInfo constructibleType in typeInfos) { if (constructibleType.GetConstructor(Type.EmptyTypes) == null || predicate != null && !predicate(constructibleType)) { continue; } foreach (var @interface in constructibleType.GetInterfaces()) { if (@interface.IsGenericType && @interface.GetGenericTypeDefinition() == typeof(IEntityTypeConfiguration <>)) { var type = @interface.GetGenericArguments().First(); var efFluentType = typeof(EfCoreTableFluent <>).MakeGenericType(type); var actionType = typeof(Action <>).MakeGenericType(efFluentType); //1.需要实体和Configuration配置 //codeFirst.Entity<ToDoItem>(eb => //{ // new ToDoItemConfiguration().Configure(eb); //}); //2.需要实体 //Action<EfCoreTableFluent<ToDoItem>> x = new Action<EfCoreTableFluent<ToDoItem>>(e => //{ // object o = Activator.CreateInstance(constructibleType); // constructibleType.GetMethod("ApplyConfiguration")?.Invoke(o, new object[1] { e }); //}); //codeFirst.Entity<ToDoItem>(x); //3.实现动态调用泛型委托 DelegateBuilder delegateBuilder = new DelegateBuilder(constructibleType); MethodInfo applyconfigureMethod = delegateBuilder.GetType().GetMethod("ApplyConfiguration")?.MakeGenericMethod(type); if (applyconfigureMethod == null) { continue; } Delegate @delegate = Delegate.CreateDelegate(actionType, delegateBuilder, applyconfigureMethod); methodInfo.MakeGenericMethod(type).Invoke(null, new object[2] { codeFirst, @delegate }); } } } return(codeFirst); }