public void Import(IAcDomain acDomain, IAcSession acSession, string appSystemCode) { if (_isChanged) { lock (Locker) { if (_isChanged) { var privilegeBigramRepository = acDomain.RetrieveRequiredService <IRepository <Privilege> >(); if (string.IsNullOrEmpty(appSystemCode)) { throw new ArgumentNullException("appSystemCode"); } AppSystemState appSystem; if (!acDomain.AppSystemSet.TryGetAppSystem(appSystemCode, out appSystem)) { throw new ValidationException("意外的应用系统码" + appSystemCode); } // TODO:提取配置 var assemblyStrings = new List <string> { "Anycmd.Ac.Web.Mvc", "Anycmd.Edi.Web.Mvc", "Anycmd.Mis.Web.Mvc" }; var dlls = assemblyStrings.Select(Assembly.Load).ToList(); var oldPages = acDomain.UiViewSet; var oldFunctions = acDomain.FunctionSet.Cast <IFunction>().ToList(); var reflectionFunctions = new List <FunctionId>(); #region 通过反射程序集初始化功能和页面列表 foreach (var dll in dlls) { // 注意这里约定区域名为二级命名空间的名字 var areaCode = dll.GetName().Name.Split('.')[1]; var types = dll.GetTypes(); var actionResultType = typeof(ActionResult); var controllerType = typeof(AnycmdController); var viewResultType = typeof(ViewResultBase); foreach (var type in types) { var isController = controllerType.IsAssignableFrom(type); // 跳过不是Controller的类型 if (!isController) { continue; } var controller = type.Name.Substring(0, type.Name.Length - "Controller".Length); var resourceCode = controller;// 注意这里约定资源码等于控制器名 var methodInfos = type.GetMethods(); int sortCode = 10; foreach (var method in methodInfos) { bool isPage = viewResultType.IsAssignableFrom(method.ReturnType); bool isAction = isPage || actionResultType.IsAssignableFrom(method.ReturnType); string action = method.Name; CatalogState resource; string description; Guid developerId; // 跳过不是Action的方法 if (!isAction) { continue; } var descriptionAttrs = method.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), inherit: false); // 如果打有描述文本标记则使用描述文本作为操作说明,否则试用Action方法名 if (descriptionAttrs.Length > 0) { description = ((DescriptionAttribute)descriptionAttrs[0]).Description; if (string.IsNullOrEmpty(description)) { description = action; } } else { description = action; } object[] byAttrs = method.GetCustomAttributes(typeof(ByAttribute), inherit: false); if (byAttrs.Length > 0) { string loginName = ((ByAttribute)byAttrs[0]).DeveloperCode; AccountState developer; if (!acDomain.SysUserSet.TryGetDevAccount(loginName, out developer)) { throw new ValidationException("意外的开发人员" + loginName + "在" + controllerType.FullName + "在" + method.Name); } developerId = developer.Id; } else { throw new ValidationException(type.FullName + method.Name); } if (!acDomain.CatalogSet.TryGetCatalog(appSystem.Code + "." + resourceCode, out resource)) { throw new ValidationException("意外的资源码" + resourceCode); } var oldFunction = oldFunctions.FirstOrDefault( o => o.ResourceTypeId == resource.Id && string.Equals(o.Code, action, StringComparison.OrdinalIgnoreCase)); if (oldFunction == null) { // TODO:持久化托管标识 var function = FunctionId.Create(Guid.NewGuid(), appSystemCode, areaCode, resourceCode, action); if (reflectionFunctions.Any(a => a.AreaCode == areaCode && a.ResourceCode == resourceCode && string.Equals(a.FunctionCode, action, StringComparison.OrdinalIgnoreCase))) { throw new ValidationException("同一Controller下不能有命名相同的Action。" + method.DeclaringType.FullName + "." + method.Name); } reflectionFunctions.Add(function); acDomain.Handle(new FunctionCreateInput() { Description = description, DeveloperId = developerId, Id = function.Id, IsEnabled = 1, IsManaged = false, ResourceTypeId = resource.Id, SortCode = sortCode, Code = function.FunctionCode }.ToCommand(acSession)); if (isPage) { acDomain.Handle(new UiViewCreateInput { Id = function.Id }.ToCommand(acSession)); } } else { // TODO:持久化托管标识 // 更新作者 if (oldFunction.DeveloperId != developerId) { acDomain.Handle(new FunctionUpdateInput { Code = oldFunction.Code, Description = oldFunction.Description, DeveloperId = developerId, Id = oldFunction.Id, SortCode = oldFunction.SortCode }.ToCommand(acSession)); } reflectionFunctions.Add(FunctionId.Create(oldFunction.Id, appSystemCode, areaCode, resourceCode, action)); if (isPage) { if (oldPages.All(a => a.Id != oldFunction.Id)) { acDomain.Handle(new UiViewCreateInput { Id = oldFunction.Id }.ToCommand(acSession)); } } else { // 删除废弃的页面 if (oldPages.All(a => a.Id != oldFunction.Id)) { acDomain.Handle(new RemoveUiViewCommand(acSession, oldFunction.Id)); } } } sortCode += 10; } } } #endregion #region 除废弃的功能 foreach (var oldFunction in oldFunctions) { if (reflectionFunctions.All(o => o.Id != oldFunction.Id)) { // 删除角色功能 var privilegeType = AcElementType.Function.ToName(); foreach (var rolePrivilege in privilegeBigramRepository.AsQueryable().Where(a => privilegeType == a.ObjectType && a.ObjectInstanceId == oldFunction.Id).ToList()) { privilegeBigramRepository.Remove(rolePrivilege); acDomain.EventBus.Publish(new PrivilegeRemovedEvent(acSession, rolePrivilege)); } acDomain.EventBus.Commit(); privilegeBigramRepository.Context.Commit(); acDomain.Handle(new RemoveFunctionCommand(acSession, oldFunction.Id)); } } #endregion _isChanged = false; } } } }