由于客户提供的复杂请求,有时我的代码会变得混乱。我花时间阅读和理解自上次工作以来我所写的内容,但这需要时间。
我想知道是否有人实现了一个好的设计模式,它可以节省时间并使代码更有条理和可读性等。
由于客户提供的复杂请求,有时我的代码会变得混乱。我花时间阅读和理解自上次工作以来我所写的内容,但这需要时间。
我想知道是否有人实现了一个好的设计模式,它可以节省时间并使代码更有条理和可读性等。
拥有一个实现 IPlugin 的基础插件是朝着正确方向迈出的一大步。它的 Execute 函数可以将 IServiceProvider 以及您的 dataContext 或 OrganizationService 传递到抽象的 onExecute 方法中,该方法包含在带有虚拟错误处理程序方法的 try catch 中。这将消除大量重复的样板代码......
添加了显示抽象 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
}
}
我在 DLaB.Xrm.Plugin 命名空间的 DLaB.Xrm(在 Nuget 上)中定义了一个插件库,可以为您处理很多很棒的事情。 这是一个示例插件类,向您展示如何使用它。
我基于 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();
}
}
我知道我可能迟到了,但是……
有几个 Visual Studio 插件模板,这些示例将让您了解什么是最好的。
我的最爱之一是: http: //pogo69.wordpress.com/2011/04/15/crm-2011-visual-studio-plugin-templates/
无论如何,您必须知道最终您的逻辑设计会改进并变得更好,您所需要的只是练习。
问候!