Git Product home page Git Product logo

netbookmaterials's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

netbookmaterials's Issues

每个项目的基础设施层都需要创建一个实体类实现IModuleInitializer这个接口,实体类中需要手动的 services.AddScoped,项目大的话,每个ModuleInitializer中会有很多的services.AddScoped(),这样会很方便?

杨老师,我把builder.ConfigureExtraServices()和 services.RunModuleInitializers(assemblies);这两个方法,都改造成可以根据外部传入的不同的接口,实现DI的自动注入,每个项目在创建ModuleInitializer实现类基础上,也可以根据传入外部参数的接口类型集合,实现框架的自动注入。下面是我实现的代码,我现在不清楚这样实现有没有性能上的损失,这样改造不知道是否合适?
builder.ConfigureExtraServices(new InitializerOptions
{
EventBusQueueName = "IdentityService.WebAPI",
LogFilePath = "D:/temp/IdentityService.log"
}, options =>
{
options.Add(typeof(IServiceSupport));
});

//获取所有的类库
var assemblies = ReflectionHelper.GetAllReferencedAssemblies();
//调整为可以根据前端传递需要注入的接口集合
services.RunModuleInitializers(assemblies, options);
//


/// 每个项目中都可以自己写一些实现了IModuleInitializer接口的类,
/// 在其中注册自己需要的服务,这样避免所有内容到入口项目中注册
/// todo:后续需要改造成所有的实现某些接口的类也直接注入框架
///

///
///
public static IServiceCollection RunModuleInitializers(this IServiceCollection services,
IEnumerable assemblies,Action option)
{
foreach(var asm in assemblies)
{
Type[] types = asm.GetTypes();
var moduleInitializerTypes = types.Where(t => !t.IsAbstract && typeof(IModuleInitializer).IsAssignableFrom(t));
foreach(var implType in moduleInitializerTypes)
{
//通过反射生成实体类,并执行内部的方法
var initializer = (IModuleInitializer?)Activator.CreateInstance(implType);
if (initializer == null)
{
throw new ApplicationException($"Cannot create ${implType}");
}
initializer.Initialize(services);
}
}

        //liuyongfei 2023年1月10日15:14:10 后续添加可以根据不同类型接口实现DI自动注入
        if (option != null)
        {
            var iocOption = new IocOption();
            option(iocOption);//客户端类型注入 
            var definedTypes = assemblies.SelectMany(y => y.DefinedTypes).ToList();
            foreach (var type in iocOption.Types)
            {
                var allTypes = definedTypes.Where(t => type.GetTypeInfo().IsAssignableFrom(t.AsType()));

                var abstractTypes = allTypes.Where(t => t.IsInterface || t.IsAbstract);
                var implTypes = allTypes.Where(t => t.IsInterface == false && t.IsAbstract == false).ToList();


                foreach (var abstractType in abstractTypes)
                {
                    if (abstractTypes.Count() > 1
                        && abstractType.AssemblyQualifiedName == type.AssemblyQualifiedName)
                    {
                        continue;
                    }
                    var _implTypes = implTypes.Where(t => t.ImplementedInterfaces.Any(impl => impl.AssemblyQualifiedName == abstractType.AssemblyQualifiedName)
                                || t.BaseType?.AssemblyQualifiedName == abstractType.AssemblyQualifiedName);
                    foreach (var implClass in _implTypes)
                    {
                        if (iocOption.ExceptTypes.Count > 0)
                        {
                            if (iocOption.ExceptTypes.Where(
                                t => t.AssemblyQualifiedName == abstractType.AssemblyQualifiedName
                                || t.AssemblyQualifiedName == implClass.AssemblyQualifiedName).Any())
                            {
                                continue;
                            }
                        }
                        //配置ScopedDI
                        services.AddScoped(abstractType, implClass);
                    }
                }
            }
        }
     
        return services;

}

Bug:Zack.EventBus包的使用中出现问题

我有两个微服务A和B,A是生产者也是自己的消费者,B是消费者,当我先启动B再启动A时,A发出的事件A自己不能监听到,B可以监听到;当我先启动A再启动B时,A自己发出的事件A自己可以监听到,B不能监听到

最后大项目代码里的Zack.DomainCommons/Models/BaseEntity.cs 里的private List<INotification> domainEvents = new();是否应该使用static修饰

今天学习该项目的时候发现,实体添加了领域事件,然后并没有自动触发该事件。
调试过程中发现Zack.DomainCommons/Models/BaseEntity.cs 里面的 private List domainEvents = new();确实能够添加成功,
但是在YouZack-VNext/Zack.Infrastructure/EFCore/MediatorExtensions.cs中的 :
var domainEvents = domainEntities
.SelectMany(x => x.Entity.GetDomainEvents())
.ToList();
里拿不到值。
经过测试,在private List domainEvents = new()上加了个static拿到值了。

切换至MySql遇到的问题总结

下载代码后,因为电脑只安装了MySql,没安装SqlServer,所以就想用MySql做数据库,没想到遇到不少问题,现在总结一下,最后还有个问题:

  1. 修改数据库配置源,用MySqlConnection代替SqlConnection(安装程序集MySql.Data和Pomelo.EntityFrameworkCore.MySql),WebApplicationBuilderExtensions.ConfigureDbConfiguration()方法里,我指定了配置表表名为小写(有些MySql云数据库对表名大小写敏感,如果不改MySql的配置,会导致Win上开发没问题,一上线就出问题)
    configBuilder.AddDbConfiguration(() => new MySqlConnection(connStr), reloadOnChange: true, reloadInterval: TimeSpan.FromSeconds(5), tableName: "t_configs");
  2. 注册所有DbContext的方法里也修改一下,WebApplicationBuilderExtensions.ConfigureExtraServices()里的services.AddAllDbContexts()里的//ctx.UseSqlServer(connStr); ctx.UseMySql(connStr, ServerVersion.AutoDetect(connStr));
  3. 转码和认证项目接口,是通过设计时工厂(IDesignTimeDbContextFactory)创建DbContext的,所以还得修改DbContextOptionsBuilderFactory里得Create()方法,//optionsBuilder.UseSqlServer(connStr); optionsBuilder.UseMySql(connStr, ServerVersion.AutoDetect(connStr));
  4. 在MySql里新建数据库与环境变量里数据库连接字符串保持一致的数据库名称;
  5. 在新建的数据库里新建表:t_configs,尤其要新建Redis的配置且启动Redis服务,否则数据库迁移时,因为Redis连接失败,导致迁移失败,启动所有项目前,还需按PPT新增Cors、RabbitMQ、JWT、FileService:SMB、ElasticSearch等及其值;
  6. 删除所有源码里已生成的Migrations文件夹,重新生成迁移目录及文件;
  7. 逐个项目迁移数据库(设置WebApi为启动项,Add-Migration,Update-Database);
  8. 数据库迁移完成后,最后我的数据库里共有14张表(含__efmigrationshistory);
    9. WebApplicationBuilderExtensions.cs文件里的ConfigureExtraServices()方法里的builder.Services.AddAuthentication();是不是多余的,因为下面有builder.Services.AddJWTAuthentication(jwtOpt);了,认证服务重复了?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.