Exemple #1
0
        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;
                    }
                }
            }
        }