8

由于客户提供的复杂请求,有时我的代码会变得混乱。我花时间阅读和理解自上次工作以来我所写的内容,但这需要时间。

我想知道是否有人实现了一个好的设计模式,它可以节省时间并使代码更有条理和可读性等。

4

3 回答 3

9

拥有一个实现 IPlugin 的基础插件是朝着正确方向迈出的一大步。它的 Execute 函数可以将 IServiceProvider 以及您的 dataContext 或 OrganizationService 传递到抽象的 onExecute 方法中,该方法包含在带有虚拟错误处理程序方法的 try catch 中。这将消除大量重复的样板代码......

编辑 1

添加了显示抽象 OnExecute 和虚拟错误处理程序的代码示例:

public abstract class PluginBase : IPlugin
{

    public void Execute(IServiceProvider serviceProvider)
    {
        try
        {
            OnExecute(serviceProvider);
        }
        catch (Exception ex)
        {
            bool rethrow = false;
            try
            {
                OnError(ex);
            }
            catch
            {
                rethrow = true;
            }

            if (rethrow)
            {
                throw;
            }
        }
        finally
        {
            OnCleanup();
        }
    }

    // method is marked as abstract, all inheriting class must implement it
    protected abstract void OnExecute(IServiceProvider serviceProvider);

    // method is virtual so if an inheriting class wishes to do something different, they can
    protected virtual void OnError(Exception ex){
        // Perform logging how ever you log:
        Logger.Write(ex);
    }

    /// <summary>
    /// Cleanup resources.
    /// </summary>
    protected virtual void OnCleanup()
    {
        // Allows inheriting class to perform any cleaup after the plugin has executed and any exceptions have been handled
    }
}

编辑 2

我在 DLaB.Xrm.Plugin 命名空间的 DLaB.Xrm(在 Nuget 上)中定义了一个插件库,可以为您处理很多很棒的事情。 是一个示例插件类,向您展示如何使用它。

于 2012-06-19T16:35:37.403 回答
3

我基于 2 类工作:

第一个叫PluginContext

using System;

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;

/// <summary>
/// The plugin context.
/// </summary>
public class PluginContext
{
    #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="PluginContext"/> class.
        /// </summary>
        /// <param name="serviceProvider">
        /// The service provider.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// </exception>
        public PluginContext(IServiceProvider serviceProvider)
        {
            if (serviceProvider == null)
            {
                throw new ArgumentNullException("serviceProvider");
            }

            // Obtain the execution context service from the service provider.
            this.PluginExecutionContext =
                (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            // Obtain the tracing service from the service provider.
            this.TracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            // Obtain the Organization Service factory service from the service provider
            var factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

            // Use the factory to generate the Organization Service.
            this.OrganizationService = factory.CreateOrganizationService(this.PluginExecutionContext.UserId);

            this.OrganizationServiceContext = new OrganizationServiceContext(this.OrganizationService);
        }

        #endregion

    #region Properties

        /// <summary>
        /// Gets the organization service.
        /// </summary>
        /// <value>
        /// The organization service.
        /// </value>
        public IOrganizationService OrganizationService { get; private set; }

        /// <summary>
        /// Gets the plugin execution context.
        /// </summary>
        /// <value>
        /// The plugin execution context.
        /// </value>
        public IPluginExecutionContext PluginExecutionContext { get; private set; }

        /// <summary>
        /// Gets the service provider.
        /// </summary>
        /// <value>
        /// The service provider.
        /// </value>
        public IServiceProvider ServiceProvider { get; private set; }

        /// <summary>
        /// Gets the tracing service.
        /// </summary>
        /// <value>
        /// The tracing service.
        /// </value>
        public ITracingService TracingService { get; private set; }

        /// <summary>
        /// Gets the organization service context.
        /// </summary>
        /// <value>
        /// The organization service context.
        /// </value>
        public OrganizationServiceContext OrganizationServiceContext { get; private set; }

        #endregion

    #region Methods

        /// <summary>
        /// The trace.
        /// </summary>
        /// <param name="message">
        /// The message.
        /// </param>
        public void Trace(string message)
        {
            if (string.IsNullOrWhiteSpace(message) || this.TracingService == null)
            {
                return;
            }

            if (this.PluginExecutionContext == null)
            {
                this.TracingService.Trace(message);
            }
            else
            {
                this.TracingService.Trace(
                    "{0}, Correlation Id: {1}, Initiating User: {2}", 
                    message, 
                    this.PluginExecutionContext.CorrelationId, 
                    this.PluginExecutionContext.InitiatingUserId);
            }
        }

        #endregion
}

第二个叫PluginBase

using System;

using Microsoft.Xrm.Sdk;

/// <summary>
///     Base class for all Plugins.
/// </summary>
public abstract class PluginBase : IPlugin
{
    #region Public Properties

    /// <summary>
    ///     Gets the entity reference.
    /// </summary>
    /// <value>
    ///     The entity reference.
    /// </value>    
    public EntityReference EntityReference { get; private set; }

    /// <summary>
    ///     Gets the plugin context.
    /// </summary>
    /// <value>
    ///     The plugin context.
    /// </value>    
    public PluginContext LocalContext { get; private set; }

    #endregion

    #region Properties

    /// <summary>
    ///     Gets a value indicating whether [ignore plugin].
    /// </summary>
    /// <value>
    ///     <c>true</c> if [ignore plugin]; otherwise, <c>false</c>.
    /// </value>
    /// <created>1/5/2014</created>
    protected virtual bool IgnorePlugin
    {
        get
        {
            return false;
        }
    }

    #endregion

    #region Public Methods and Operators

    /// <summary>
    /// Executes the specified service provider.
    /// </summary>
    /// <param name="serviceProvider">
    /// The service provider.
    /// </param>    
    public void Execute(IServiceProvider serviceProvider)
    {
        if (this.IgnorePlugin)
        {
            return;
        }

        this.LocalContext = new PluginContext(serviceProvider);

        if (!this.LocalContext.PluginExecutionContext.InputParameters.Contains("Target"))
        {
            return;
        }

        var entity = this.LocalContext.PluginExecutionContext.InputParameters["Target"] as Entity;
        if (entity != null)
        {
            this.EntityReference = entity.ToEntityReference();
        }
        else
        {
            this.EntityReference =
                this.LocalContext.PluginExecutionContext.InputParameters["Target"] as EntityReference;
            if (this.EntityReference == null)
            {
                return;
            }
        }

        this.Execute();
    }

    /// <summary>
    ///     Executes this instance.
    /// </summary>    
    public abstract void Execute();

    #endregion
}

插件类将是这样的:

public class SamplePlugin : PluginBase
{
    // If don't want the plugin to be executed then override the IgnorePlugin property

    protected override bool IgnorePlugin
    {
        get
        {
            return true;
        }
    }

    public override void Execute()
    {
        var query = LocalContext
            .OrganizationServiceContext
            .CreateQuery("account")
            .Where(a => (string)a["accountname"] == "test accounts")
            .ToList();
    }
}
于 2014-01-08T08:56:49.153 回答
2

我知道我可能迟到了,但是……

有几个 Visual Studio 插件模板,这些示例将让您了解什么是最好的。

我的最爱之一是: http: //pogo69.wordpress.com/2011/04/15/crm-2011-visual-studio-plugin-templates/

无论如何,您必须知道最终您的逻辑设计会改进并变得更好,您所需要的只是练习。

问候!

于 2013-03-12T19:25:15.383 回答