Пример #1
0
            private PluginMethod CreateFrom(System.Reflection.MethodInfo method, string logicalname)
            {
                var result = new PluginMethod();

                result.method = method;
                var parameters = method.GetParameters().ToArray();

                result.Parameters = new TypeCache[parameters.Length];
                var ix = 0;

                foreach (var parameter in parameters)
                {
                    result.Parameters[ix] = TypeCache.ForParameter(parameter, logicalname);
                    ix++;
                }

                var sortAttr = method.GetCustomAttributes(Types.SortAttribute, false).SingleOrDefault();

                if (sortAttr != null)
                {
                    result.Sort = (int)sortAttr.GetType().GetProperty("Value").GetValue(sortAttr);
                }
                else
                {
                    result.Sort = 1;
                }
                return(result);
            }
Пример #2
0
        public object Resolve(TypeCache type)
        {
            try
            {
                if (services.ContainsKey(type.ObjectInstanceKey))
                {
                    return(services[type.ObjectInstanceKey]);
                }

                if (type.IsTarget && !type.IsReference)
                {
                    var entity = (Microsoft.Xrm.Sdk.Entity)pluginExecutionContext.InputParameters["Target"];
                    services[type.ObjectInstanceKey] = Extensions.Sdk.KiponSdkGeneratedExtensionMethods.ToEarlyBoundEntity(entity);
                    return(services[type.ObjectInstanceKey]);
                }

                if (type.IsPreimage)
                {
                    var imgName = PluginMethod.ImageSuffixFor(1, pluginExecutionContext.Stage, pluginExecutionContext.Mode == 1);
                    var entity  = (Microsoft.Xrm.Sdk.Entity)pluginExecutionContext.PreEntityImages[imgName];
                    services[type.ObjectInstanceKey] = Extensions.Sdk.KiponSdkGeneratedExtensionMethods.ToEarlyBoundEntity(entity);
                    return(services[type.ObjectInstanceKey]);
                }

                if (type.IsPostimage)
                {
                    var imgName = PluginMethod.ImageSuffixFor(2, pluginExecutionContext.Stage, pluginExecutionContext.Mode == 1);
                    var entity  = (Microsoft.Xrm.Sdk.Entity)pluginExecutionContext.PostEntityImages[$"postimage{imgName}"];
                    services[type.ObjectInstanceKey] = Extensions.Sdk.KiponSdkGeneratedExtensionMethods.ToEarlyBoundEntity(entity);
                    return(services[type.ObjectInstanceKey]);
                }

                if (type.IsMergedimage)
                {
                    var target = (Microsoft.Xrm.Sdk.Entity)pluginExecutionContext.InputParameters["Target"];
                    var merged = new Microsoft.Xrm.Sdk.Entity();
                    merged.Id          = target.Id;
                    merged.LogicalName = target.LogicalName;

                    var imgName = PluginMethod.ImageSuffixFor(1, pluginExecutionContext.Stage, pluginExecutionContext.Mode == 1);
                    var pre     = (Microsoft.Xrm.Sdk.Entity)pluginExecutionContext.PreEntityImages[imgName];

                    foreach (var attr in pre.Attributes.Keys)
                    {
                        merged[attr] = pre[attr];
                    }

                    foreach (var attr in target.Attributes.Keys)
                    {
                        merged[attr] = target[attr];
                    }

                    services[type.ObjectInstanceKey] = Extensions.Sdk.KiponSdkGeneratedExtensionMethods.ToEarlyBoundEntity(merged);
                    return(services[type.ObjectInstanceKey]);
                }

                if (type.IsReference)
                {
                    var target = (Microsoft.Xrm.Sdk.EntityReference)pluginExecutionContext.InputParameters["Target"];
                    if (type.Constructor != null)
                    {
                        services[type.ObjectInstanceKey] = type.Constructor.Invoke(new object[] { target });
                    }
                    else
                    {
                        services[type.ObjectInstanceKey] = target;
                    }
                    return(services[type.ObjectInstanceKey]);
                }

                if (type.FromType == typeof(Microsoft.Xrm.Sdk.IOrganizationService))
                {
                    return(this.GetOrganizationService(type.RequireAdminService));
                }

                if (type.IsQuery)
                {
                    var uow           = this.GetIUnitOfWork(type.RequireAdminService);
                    var queryProperty = type.RepositoryProperty;
                    var repository    = queryProperty.GetValue(uow, new object[0]);
                    var queryMethod   = type.QueryMethod;
                    return(queryMethod.Invoke(repository, new object[0]));
                }

                if (type.FromType == typeof(Guid))
                {
                    if (type.Name.ToLower() == "id")
                    {
                        return(pluginExecutionContext.PrimaryEntityId);
                    }

                    if (type.Name.ToLower() == "listid")
                    {
                        return(pluginExecutionContext.InputParameters["ListId"]);
                    }

                    if (type.Name.ToLower() == "entityid")
                    {
                        return(pluginExecutionContext.InputParameters["EntityId"]);
                    }

                    throw new Exceptions.UnresolveableParameterException(type.FromType, type.Name);
                }

                return(this.CreateServiceInstance(type));
            }
            catch (System.Collections.Generic.KeyNotFoundException)
            {
                var typeName = (type?.FromType?.FullName) ?? "type was null";
                var key      = type?.ObjectInstanceKey ?? "object instance key as null";
                throw new InvalidPluginExecutionException($"Unable to resolve service {typeName}, {key} or one of its dependencies.");
            }
        }
Пример #3
0
            private void AddIfConsistent(Type type, System.Reflection.MethodInfo method, List <PluginMethod> results, PluginMethod result, string message, int stage)
            {
                #region validate pre and post image consistancy
                switch (stage)
                {
                case 10:
                case 20:
                    /* pre image pre event */
                    if (result.HasPreimageThatIsNotMergedImage() && message == "Create")
                    {
                        throw new Exceptions.UnavailableImageException(type, method, "Preimage", stage, message);
                    }
                    /* post image pre event */
                    if (result.HasPostimage())
                    {
                        throw new Exceptions.UnavailableImageException(type, method, "Postimage", stage, message);
                    }
                    break;

                case 40:
                case 41:
                    if (result.HasPostimage() && message == "Delete")
                    {
                        throw new Exceptions.UnavailableImageException(type, method, "Postimage", stage, message);
                    }
                    break;
                }
                #endregion

                #region validate target consistancy
                if (result.HasTargetBesideReference() && message == "Delete")
                {
                    throw new Exceptions.UnavailableImageException(type, method, "Target", stage, message);
                }

                if (result.HasTargetReference())
                {
                    var inError = true;
                    if (message == "Delete")
                    {
                        // delete always provides an entity reference as target, everything is good
                        inError = false;
                    }

                    var mess = message.Split('_');
                    if (mess.Length >= 2)
                    {
                        // this looks a lot like a custom action, it has the pattern prefix_name, bounded actions will also provide an entity reference, so we are good
                        inError = false;
                    }

                    // ADD other conditions where target is relevant, ex associate

                    if (inError)
                    {
                        throw new Exceptions.UnavailableImageException(type, method, "Target", stage, message);
                    }
                }
                #endregion

                results.Add(result);

                if (result.method.ReturnType != null)
                {
                    var outputProperties = result.method.ReturnType.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
                    if (outputProperties != null && outputProperties.Length > 0)
                    {
                        var output = new Dictionary <System.Reflection.PropertyInfo, Output>();
                        foreach (var p in outputProperties)
                        {
                            var outputAttr = p.GetCustomAttribute(Types.OutputAttribute);
                            if (outputAttr != null)
                            {
                                var name = (string)outputAttr.GetType().GetProperty("LogicalName").GetValue(outputAttr);
                                var req  = (bool)outputAttr.GetType().GetProperty("Required").GetValue(outputAttr);
                                output.Add(p, new Output {
                                    LogicalName = name, Requred = req
                                });
                            }
                        }
                        if (output.Count > 0)
                        {
                            result.OutputProperties = output;
                        }
                    }
                }
            }
Пример #4
0
        public object Resolve(TypeCache type, Microsoft.Xrm.Sdk.IOrganizationService orgService)
        {
            try
            {
                if (services.ContainsKey(type.ObjectInstanceKey))
                {
                    return(services[type.ObjectInstanceKey]);
                }

                lock (locks)
                {
                    if (services.ContainsKey(type.ObjectInstanceKey))
                    {
                        return(services[type.ObjectInstanceKey]);
                    }

                    if (type.FromType == typeof(Guid) && type.Name != null && type.Name.ToLower() == nameof(this.pluginExecutionContext.PrimaryEntityId).ToLower())
                    {
                        return(this.pluginExecutionContext.PrimaryEntityId);
                    }

                    if (type.FromType == typeof(string) && type.Name != null && type.Name.ToLower() == nameof(this.pluginExecutionContext.PrimaryEntityName).ToLower())
                    {
                        return(this.pluginExecutionContext.PrimaryEntityName);
                    }

                    if (type.FromType == typeof(string) && type.Name != null && type.Name.ToLower() == nameof(BasePlugin.UnsecureConfig).ToLower())
                    {
                        return(this.UnsecureConfig);
                    }

                    if (type.FromType == typeof(string) && type.Name != null && type.Name.ToLower() == nameof(BasePlugin.SecureConfig).ToLower())
                    {
                        return(this.SecureConfig);
                    }

                    if (type.FromType == typeof(Microsoft.Xrm.Sdk.Query.QueryExpression))
                    {
                        if (pluginExecutionContext.InputParameters.Contains("Query"))
                        {
                            var query = pluginExecutionContext.InputParameters["Query"];
                            if (query is Microsoft.Xrm.Sdk.Query.QueryExpression qe)
                            {
                                // no cache by design - need to be resolved on all request.
                                return(qe);
                            }

                            if (query is Microsoft.Xrm.Sdk.Query.FetchExpression fe)
                            {
                                var resp = (Microsoft.Crm.Sdk.Messages.FetchXmlToQueryExpressionResponse)orgService.Execute(new Microsoft.Crm.Sdk.Messages.FetchXmlToQueryExpressionRequest
                                {
                                    FetchXml = fe.Query
                                });
                                return(resp.Query);
                            }

                            throw new Exceptions.UnresolvedQueryParameter(type.Name);
                        }
                        else
                        {
                            throw new InvalidPluginExecutionException("QueryExpression can only be requested for RetrieveMultiple requests");
                        }
                    }

                    if (type.IsTarget && !type.IsReference)
                    {
                        var entity = (Microsoft.Xrm.Sdk.Entity)pluginExecutionContext.InputParameters["Target"];
                        services[type.ObjectInstanceKey] = Extensions.Sdk.KiponSdkGeneratedExtensionMethods.ToEarlyBoundEntity(entity);
                        return(services[type.ObjectInstanceKey]);
                    }

                    if (type.IsPreimage)
                    {
                        var imgName = PluginMethod.ImageSuffixFor(1, pluginExecutionContext.Stage, pluginExecutionContext.Mode == 1);
                        var entity  = (Microsoft.Xrm.Sdk.Entity)pluginExecutionContext.PreEntityImages[imgName];
                        services[type.ObjectInstanceKey] = Extensions.Sdk.KiponSdkGeneratedExtensionMethods.ToEarlyBoundEntity(entity);
                        return(services[type.ObjectInstanceKey]);
                    }

                    if (type.IsPostimage)
                    {
                        var imgName = PluginMethod.ImageSuffixFor(2, pluginExecutionContext.Stage, pluginExecutionContext.Mode == 1);
                        var entity  = (Microsoft.Xrm.Sdk.Entity)pluginExecutionContext.PostEntityImages[$"postimage{imgName}"];
                        services[type.ObjectInstanceKey] = Extensions.Sdk.KiponSdkGeneratedExtensionMethods.ToEarlyBoundEntity(entity);
                        return(services[type.ObjectInstanceKey]);
                    }

                    if (type.IsMergedimage)
                    {
                        var merged = new Microsoft.Xrm.Sdk.Entity();

                        var target = pluginExecutionContext.InputParameters["Target"] as Microsoft.Xrm.Sdk.Entity;

                        if (target != null)
                        {
                            merged.Id          = target.Id;
                            merged.LogicalName = target.LogicalName;
                        }
                        else
                        {
                            var er = pluginExecutionContext.InputParameters["Target"] as Microsoft.Xrm.Sdk.EntityReference;
                            merged.Id          = er.Id;
                            merged.LogicalName = er.LogicalName;
                        }

                        if (pluginExecutionContext.MessageName == "Create")
                        {
                            merged = target;
                        }
                        else
                        {
                            var imgName = PluginMethod.ImageSuffixFor(1, pluginExecutionContext.Stage, pluginExecutionContext.Mode == 1);
                            var pre     = (Microsoft.Xrm.Sdk.Entity)pluginExecutionContext.PreEntityImages[imgName];

                            foreach (var attr in pre.Attributes.Keys)
                            {
                                merged[attr] = pre[attr];
                            }

                            if (target != null)
                            {
                                foreach (var attr in target.Attributes.Keys)
                                {
                                    merged[attr] = target[attr];
                                }
                            }
                        }

                        services[type.ObjectInstanceKey] = Extensions.Sdk.KiponSdkGeneratedExtensionMethods.ToEarlyBoundEntity(merged);
                        return(services[type.ObjectInstanceKey]);
                    }

                    if (type.IsReference)
                    {
                        var target = (Microsoft.Xrm.Sdk.EntityReference)pluginExecutionContext.InputParameters["Target"];
                        if (type.Constructor != null)
                        {
                            services[type.ObjectInstanceKey] = type.Constructor.Invoke(new object[] { target });
                        }
                        else
                        {
                            services[type.ObjectInstanceKey] = target;
                        }
                        return(services[type.ObjectInstanceKey]);
                    }

                    if (type.FromType == typeof(Microsoft.Xrm.Sdk.IOrganizationService))
                    {
                        return(this.GetOrganizationService(type.RequireAdminService));
                    }

                    if (type.IsQuery)
                    {
                        var uow = this.GetIUnitOfWork(type.RequireAdminService);
                        var repositoryProperty = type.RepositoryProperty;
                        var repository         = repositoryProperty.GetValue(uow, new object[0]);
                        var queryMethod        = type.QueryMethod;
                        return(queryMethod.Invoke(repository, new object[0]));
                    }

                    if (type.IsRepository)
                    {
                        var uow           = this.GetIUnitOfWork(type.RequireAdminService);
                        var queryProperty = type.RepositoryProperty;
                        return(queryProperty.GetValue(uow, new object[0]));
                    }

                    if (type.IsEntityCache)
                    {
                        var uow           = this.GetIUnitOfWork(type.RequireAdminService);
                        var cacheProperty = uow.GetType().GetProperty("Cache");
                        return(cacheProperty.GetValue(uow, new object[0]));
                    }

                    if (type.FromType == typeof(Guid))
                    {
                        if (type.Name.ToLower() == "id")
                        {
                            return(pluginExecutionContext.PrimaryEntityId);
                        }

                        if (type.Name.ToLower() == "listid")
                        {
                            return(pluginExecutionContext.InputParameters["ListId"]);
                        }

                        if (type.Name.ToLower() == "entityid")
                        {
                            return(pluginExecutionContext.InputParameters["EntityId"]);
                        }

                        throw new Exceptions.UnresolveableParameterException(type.FromType, type.Name);
                    }

                    if (type.FromType == typeof(Microsoft.Xrm.Sdk.Relationship))
                    {
                        if (pluginExecutionContext.InputParameters.Contains("Relationship"))
                        {
                            return((Microsoft.Xrm.Sdk.Relationship)pluginExecutionContext.InputParameters["Relationship"]);
                        }

                        throw new InvalidPluginExecutionException("Relationship is requested as input parameter but there is no such information in the payload");
                    }

                    return(this.CreateServiceInstance(type));
                }
            }
            catch (System.Collections.Generic.KeyNotFoundException)
            {
                var typeName = (type?.FromType?.FullName) ?? "type was null";
                var key      = type?.ObjectInstanceKey ?? "object instance key as null";
                throw new InvalidPluginExecutionException($"Unable to resolve service {typeName}, {key} or one of its dependencies.");
            }
        }
Пример #5
0
            private void AddIfConsistent(Type type, System.Reflection.MethodInfo method, List <PluginMethod> results, PluginMethod result, string message, int stage)
            {
                #region validate pre and post image consistancy
                switch (stage)
                {
                case 10:
                case 20:
                    /* pre image pre event */
                    if (result.HasPreimage() && message == "Create")
                    {
                        throw new Exceptions.UnavailableImageException(type, method, "Preimage", stage, message);
                    }
                    /* post image pre event */
                    if (result.HasPostimage())
                    {
                        throw new Exceptions.UnavailableImageException(type, method, "Postimage", stage, message);
                    }
                    break;

                case 40:
                case 41:
                    if (result.HasPostimage() && message == "Delete")
                    {
                        throw new Exceptions.UnavailableImageException(type, method, "Postimage", stage, message);
                    }
                    break;
                }
                #endregion

                #region validate target consistancy
                if (result.HasTargetBesideReference() && message == "Delete")
                {
                    throw new Exceptions.UnavailableImageException(type, method, "Target", stage, message);
                }

                if (result.HasTargetReference())
                {
                    var inError = true;
                    if (message == "Delete")
                    {
                        inError = false;
                    }

                    // ADD other conditions where target is relevant, ex associate

                    if (inError)
                    {
                        throw new Exceptions.UnavailableImageException(type, method, "Target", stage, message);
                    }
                }
                #endregion

                results.Add(result);
            }