{"id":19991052,"url":"https://github.com/ChengLab/AAFrameWork","last_synced_at":"2025-05-04T10:31:02.082Z","repository":{"id":33372241,"uuid":"140360826","full_name":"ChengLab/AAFrameWork","owner":"ChengLab","description":"AA.Framework is built on the popular open source class library of NET Core","archived":false,"fork":false,"pushed_at":"2022-12-08T01:34:16.000Z","size":236,"stargazers_count":129,"open_issues_count":5,"forks_count":47,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-05T20:06:56.339Z","etag":null,"topics":["automapper","bus","csharp","dapper","dapper-fluentmap","dommel","dotnet-core","dotnetcore-2-1","log4net","masstransit","nlog","rabbitmq","redis"],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ChengLab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-07-10T01:29:20.000Z","updated_at":"2024-03-07T08:13:03.000Z","dependencies_parsed_at":"2023-01-15T00:38:17.161Z","dependency_job_id":null,"html_url":"https://github.com/ChengLab/AAFrameWork","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChengLab%2FAAFrameWork","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChengLab%2FAAFrameWork/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChengLab%2FAAFrameWork/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChengLab%2FAAFrameWork/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ChengLab","download_url":"https://codeload.github.com/ChengLab/AAFrameWork/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252320076,"owners_count":21729061,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automapper","bus","csharp","dapper","dapper-fluentmap","dommel","dotnet-core","dotnetcore-2-1","log4net","masstransit","nlog","rabbitmq","redis"],"created_at":"2024-11-13T04:51:35.868Z","updated_at":"2025-05-04T10:30:59.023Z","avatar_url":"https://github.com/ChengLab.png","language":"C#","readme":"# AA.FrameWork\nAA.Framework is built on the popular open source class library of NET Core\n\n## Completed list\n- [ ] log：Log4net\n- [ ] object mapper：automapper\n- [ ] orm：dapper（Dapper-FluentMap,Dommel）\n- [ ] MQ：RabbitMQ.Client\n- [ ] Redis：StackExchange.Redis\n- [ ] message bus：MassTransit\n- [x] more.....\n## Nuget Packages\n\nPackage| nuget | description\n---|--- |---\nAA.Dapper | [nuget](https://www.nuget.org/packages/AA.Dapper/) | 基于dapper，Dapper-FluentMap 开发 ， 支持工作单元、仓储模式和原生dapper的操作\nAA.Log4Net | [nuget](https://www.nuget.org/packages/AA.Log4Net/) | 基于Log4net开发，提供常用的日志操作类\nAA.FrameWork  | [nuget](https://www.nuget.org/packages/AA.FrameWork/) | 基础框架\nAA.Redis  | [nuget](https://www.nuget.org/packages/AA.Redis/) | 基于StackExchange.Redis开发，提供各种redis操作和基于redis的分布式锁\nAA.AutoMapper  | [nuget](https://www.nuget.org/packages/AA.AutoMapper/) | 基于AutoMapper开发，对象映射\nAA.ServiceBus  | [nuget](https://www.nuget.org/packages/AA.ServiceBus/) | 基于MassTransit开发的服务总线 ；很方便的应用在event bus 和 publish/subscribe 场景\nAA.AspNetCore  | [nuget](https://www.nuget.org/packages/AA.AspNetCore/) | aspnetcore常用类集合\n\n## AA.Dapper用法\n#### 实体映射配置\n使用DommelEntityMap\u003cTEntity\u003e类映射属性名称。创建一个派生类，在构造函数中设置Map方法，可指定某个属性映射到数据库列名\n\n```\n   public class UserInfoMap : DommelEntityMap\u003cUserInfo\u003e\n    {\n        public UserInfoMap()\n        {\n            ToTable(\"Sys_UserInfo\");//映射具体的表名\n            Map(p =\u003e p.SysNo).IsKey();//指定主键 ,IsIdentity是否自增\n            Map(p=\u003ep.GmtCreate).ToColumn(\"GmtCreateDate\"); //属性名和数据库列名 可以不同\n            Map(p=\u003ep.LastLoginDate).Ignore();//一些计算属性，可以忽略不需要跟数据库列进行映射\n        }\n    }\n```\n\n使用MapConfiguration.Init方法，把映射类初始化，后续就可以使用了\n\n```\n public static void InitMapCfgs()\n        {\n            var fluentMapconfig = new List\u003cAction\u003cFluentMapConfiguration\u003e\u003e();\n            fluentMapconfig.Add(cfg =\u003e\n            {\n                cfg.AddMap(new UserInfoMap());\n            });\n            MapConfiguration.Init(fluentMapconfig);\n        }\n```\n\n####  开始使用AA.Dapper\n##### 使用DapperContext设置数据库连接和数据库类型是sqlserver还是mysql\n\n```\n    public class AADapperContext : DapperContext\n    {\n        public AADapperContext() : base(new NameValueCollection()\n        {\n            [\"aa.dataSource.AaCenter.connectionString\"] = \"Data Source =.; Initial Catalog = AaCenter;User ID = sa; Password = 123;\",\n            [\"aa.dataSource.AaCenter.provider\"] = \"SqlServer\"\n        })\n        { }\n    }\n```\n##### 仓储包含了大部分的操作，同时支持Async操作\n\n```\nIDapperRepository\u003cUserInfo\u003e userInfoRepository = new DapperRepository\u003cUserInfo\u003e();\n```\n###### 插入实体\n\n```\n var user = new UserInfo()\n            {\n                UserName = \"chengTian\",\n                RealName = \"成天\",\n                GmtCreate = DateTime.Now,\n                GmtModified = DateTime.Now\n            };\n  var result = userInfoRepository.Insert(user);\n```\n###### 修改实体\n\n```\n var user = userInfoRepository.Get(1);\n            user.GmtModified = DateTime.Now;\n var result = userInfoRepository.Update(user);\n```\n###### 获取实体\n\n```\n   var user = userInfoRepository.Get(1);//By 主键\n   var users = userInfoRepository.GetAll();//所有\n   var users = userInfoRepository.Select(p =\u003e p.UserName == \"chengTian\");//谓词\n```\n###### 删除实体\n\n```\n   var user = userInfoRepository.Get(1);\n   var result = userInfoRepository.Delete(user);\n```\n###### 分页\n\n```\nvar result = _userRepository.From(sql =\u003e  \n            {  \n                sql.Select()  \n                   .Where(x=\u003ex.UserName==input.UserName)  \n                   .Page(input.PageIndex, input.PageSize);  \n            });  \n```\n###### 事务\n\n```\nusing (var dbTransaction = dapperContext.BeginTransaction())  \n {  \n     try  \n     {  \n         var user = new UserInfo()  \n         {  \n             UserName = \"chengTian\",  \n             RealName = \"成天\",  \n             GmtCreate = DateTime.Now,  \n             GmtModified = DateTime.Now,  \n             LastLoginDate = DateTime.Now  \n         };  \n         userInfoRepository.Insert(user);  \n         userAlbumRepository.Insert(new UserAlbum  \n         {  \n             Pic = \"image/one.jgp\"  \n         });  \n         dapperContext.Commit();  \n     }  \n     catch (Exception ex)  \n     {  \n         dbTransaction.Rollback();  \n     }  \n }  \n \n```\n###### 动态Expression\n\n```\nvar where = DynamicWhereExpression.Init\u003cUser\u003e();  \nif (input.RealName != \"\")  \n{  \n   where = where.And(x =\u003e x.RealName.Contains(input.RealName));  \n}  \nif (input.SysNo!=Guid.Empty)   \n{  \n    where = where.And(x=\u003ex.SysNo==input.SysNo);  \n}  \nif (input.SysNos.Any())   \n{  \n    where = where.And(x=\u003einput.SysNos.Contains(x.SysNo));  \n}  \nvar result = _userRepository.From(sql =\u003e  \n{  \n    sql.Select()  \n       .Where(where)  \n       .Page(input.PageIndex, input.PageSize);  \n});  \n```\n\n###### 支持Dapper原生操作\n操作基本的封装都是单表的操作，可以满足一部分业务开发，有些业务场景编写sql还是比较合适的比如报表和一些复杂的查询，推荐使用原生dapper的操作\n\n```\npublic class UserInfoRepository : DapperRepository\u003cUserInfo\u003e, IUserInfoRepository\n    {\n      \n        public IEnumerable\u003cUserInfo\u003e QueryAll()\n        {\n            var result = DapperContext.Current.DataBase.Query\u003cUserInfo\u003e(\"SELECT * from  [Sys_UserInfo]\");//实例\n            return result;\n        }\n    }\n```\n## AA.Log4Net 用法\n\n1. log4net.config 配置，并将log4net.config的属性-\u003e复制到输出目录-\u003e设置为-\u003e始终复制\n1.  Log4NetLogger.Use(\"配置文件名或者路径+配置文件名\"); 例如：log4net.config文件在根目录下，Log4NetLogger.Use(\"log4net.config\");如果在自定义文件中；例如config/log4net.config 则Log4NetLogger.Use(\"config/log4net.config\")\n1. ILog log= Logger.Get(typeof(类));\nlog.Debug(\"example\");\n\n## AA.ServiceBus 用法\n###### 生产者（事件和命令两种类型）\n 实例化bus\n```\n //事件\n IBusControl busControl = ServiceBusManager.Instance.UseRabbitMq(rabbitMqUri, rabbitMqUserName, rabbitMqPassword)\n                         .BuildEventProducer();\n //命令\n ISendEndpoint busControl = ServiceBusManager.Instance.UseRabbitMq(rabbitMqUri, rabbitMqUserName, rabbitMqPassword)\n                         .BuildCommandProducer(queueName);\n```\n \n实例化bus之后可以使用发送和发布两个方法\n\n```\n  //命令\n  TaskUtil.Await(busControl.Send\u003cSubmitOrder\u003e(new\n            {\n                Id = 10\n            }));\n   //事件          \n   TaskUtil.Await(busControl.Publish\u003cOrderSubmitted\u003e(new\n            {\n                Id = 1\n            }));\n```\n###### 消费者\n\n```\n  [Fact]\n        public void TestConsumer()\n        {\n            Log4NetLogger.Use(\"Log4Net/log4net.config\");\n            string rabbitMqUri = \"rabbitmq://localhost:5672\";\n            string rabbitMqUserName = \"\";\n            string rabbitMqPassword = \"\";\n            string queueName = \"order.queue\";\n\n            var busControl = ServiceBusManager.Instance.UseRabbitMq(rabbitMqUri, rabbitMqUserName, rabbitMqPassword)\n             .RegisterConsumer\u003cSubmitOrderCommandConsumer\u003e(queueName)//注册命令消费者\n             .RegisterConsumer\u003cOrderSubmittedEventConsumer\u003e(null)//注册事件消费者\n             .Build();\n            busControl.Start();\n\n        }\n```\n定义消费者需要实现接口IConsumer\n\n```\npublic class OrderSubmittedEventConsumer : IConsumer\u003cOrderSubmitted\u003e\n    {\n        public async Task Consume(ConsumeContext\u003cOrderSubmitted\u003e context)\n        {\n            var @event = context.Message;\n\n            var result = $\"OrderSubmittedEvent {@event.Id.ToString()}\";\n            ILog log = Logger.Get(typeof(OrderSubmittedEventConsumer));\n            log.Debug(result);\n            //do somethings...\n        }\n    }\n\n\n    public class SubmitOrderCommandConsumer : IConsumer\u003cSubmitOrder\u003e\n    {\n        public async Task Consume(ConsumeContext\u003cSubmitOrder\u003e context)\n        {\n            var command = context.Message;\n\n            var result = $\"CreateFooCommand {command.Id.ToString()}\";\n            ILog log = Logger.Get(typeof(SubmitOrderCommandConsumer));\n            log.Debug(result);\n            //do somethings...\n        }\n    }\n```\n## AA.AutoMapper用法\n##### 实现IMapperConfiguration接口，创建映射规则配置\n\n```\n public class WebMapperConfigurations : IMapperConfiguration\n    {\n        public int Order { get { return 0; } }\n\n        public Action\u003cIMapperConfigurationExpression\u003e  GetConfiguration()\n        {\n            Action\u003cIMapperConfigurationExpression\u003e action = cfg =\u003e\n            {\n                cfg.CreateMap\u003cUserVm, UserInput\u003e();\n            };\n            return action;\n        }\n    }\n```\n#####  在程序startup调用配置\n\n```\n     var mapperConfig = new WebMapperConfigurations();\n     AutoMapperConfiguration.Init(new List\u003cAction\u003cIMapperConfigurationExpression\u003e\u003e { mapperConfig.GetConfiguration() });\n     ObjectMapping.ObjectMapManager.ObjectMapper = new AutoMapperObjectMapper();\n```\n#####  利用扩展方法MapTo执行映射\n\n```\n [Fact]\n        public void TestMap()\n        {\n            //init\n            Init();\n            UserVm userVm = new UserVm { Id = 1, Name = \"成天\" ,Remark=\"微信公众号:dotNet知音\"};\n            var userDto = userVm.MapTo\u003cUserInput\u003e();\n            //var userDto2 = userVm.MapTo\u003cUserVm,UserInput\u003e();\n\n        }\n```\n","funding_links":[],"categories":["C\\#"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FChengLab%2FAAFrameWork","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FChengLab%2FAAFrameWork","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FChengLab%2FAAFrameWork/lists"}