2013-06-08 2 views
0

최근에 Execute 메서드에서 CRM 개체를 가져오고 별도의 메서드로 플러그 인/워크 플로 비즈니스 논리를 수행하기 시작했습니다.
이 방법을 개선 (또는 삭제할 수 있습니까?
LINQ를 사용하여 워크 플로의 대상 레코드를 가져올 수 있습니까?
입력 매개 변수보다 더 편리합니다. 또한 워크 플로는 비동기 적이며 사용자 환경에 영향을 미치지 않습니다. 플러그인에서Microsoft Dynamics CRM 2011의 워크 플로 및 플러그인 모범 사례

:

public class AddEmailAttachments : IPlugin 
    { 
     private void AddAttachments(Entity target, IOrganizationService service, Context linq) 
     { 
      // Business logic 
     } 
     /* 
     * Get all the Objects that we need 
     * and call AddAttachments 
     * */ 
     public void Execute(IServiceProvider serviceProvider) 
     { 
      IPluginExecutionContext context = null; 
      IOrganizationServiceFactory factory = null; 
      IOrganizationService service = null; 
      Entity target = null; 
      Context linq = null; 
      try // and get the services we need 
      { 
       context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); 
       factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); 
       service = factory.CreateOrganizationService(context.UserId); 
       target = (Entity)context.InputParameters["Target"]; 
       linq = new Context(service); 
       if (service != null && target != null && linq != null) 
        AddAttachments(target, service, linq); 
      } 
      catch (Exception) { }; // this is strict because if this plugin fails then the email will not be created in CRM and disrupt the business process 

     } 
    } 

워크 플로우 :

public class SendCaseNotifications : CodeActivity 
    { 
     /* Receives the necessary Objects and 
     * Sends the email 
     * */ 
     private void SendNotifications(Incident incident, IOrganizationService service, Email email, Context linq) 
     { 
      // Perform business logic 
     } 
     /* Get the Objects that are required and call 
     * the method 
     * */ 
     protected override void Execute(CodeActivityContext context) 
     { 
      IWorkflowContext workflowContext = context.GetExtension<IWorkflowContext>(); 
      IOrganizationServiceFactory factory = context.GetExtension<IOrganizationServiceFactory>(); 
      IOrganizationService service = factory.CreateOrganizationService(workflowContext.InitiatingUserId); 
      Entity target = workflowContext.InputParameters["Target"] as Entity; 
      Incident incident = null; 
      Email email = null; 
      Context linq = new Context(service); 
      IEnumerable<Incident> incidentQuery = from incidents in linq.IncidentSet where incidents.Id.Equals(target.Id) select incidents; 
      if (incidentQuery.Any()) 
       incident = incidentQuery.First(); 
      if (incident == null) 
       throw new InvalidPluginExecutionException("Unable to retrieve Case with id: " + target.Id.ToString() + ". Re-try the operation or contact the system administrator."); 
      IEnumerable<Email> emailQuery = from emails in linq.EmailSet where emails.Id.Equals(incident.mda_originatingemail.Id) select emails; 
      if (emailQuery.Any()) 
       email = emailQuery.First(); 
      if (email == null) 
       throw new InvalidPluginExecutionException("Unable to retrieve Email with id: " + incident.mda_originatingemail.Id.ToString() + ". Re-try the operation or contact the system administrator."); 
      SendNotifications(incident, service, email, linq); 
     } 
    } 

I는 가능한 한 많은 예외 취급을 실행하고 실제 작업을 수행하는 방법에 객체를 전달한다.
최근에 동기식 플러그인이 예외를 throw하는 경우 비즈니스 프로세스에 영향을 줄 수있는 어려운 방법을 배웠습니다.

+0

[CRM 2011 플러그인 작성을위한 최상의 디자인 패턴] (http://stackoverflow.com/questions/11097356/best-design-pattern-for-writing-crm-2011-plugins) – Daryl

답변

2

=>이 접근법을 개선 (또는 삭제할 수 있습니까?) 수 있습니까?

몇 가지 방법으로 개선 할 수 있습니다. 이를 개선 할 수있는 가장 큰 방법은 컨텍스트, orgservice 등을 모두 추출하는 작업을 자동으로 수행하는 플러그인 및 워크 플로 활동을위한 기본 클래스를 만드는 것입니다.이 단계를 조금 더 진행하고 Create/업데이트/삭제/SetState/etc 플러그인은 입력 및 출력 매개 변수를 적절하게 추출합니다.

둘째, 전체 OO 설계를 원한다면 모든 비즈니스 로직을 기능 대신 별도의 클래스에 넣을 수 있습니다. 그것은 결합이 적고, 복잡한 논리를 위해보다 체계적으로 구성되며, 단위 테스트를 원한다면 테스트 할 수 있습니다.

2 => LINQ를 사용하여 워크 플로의 대상 레코드를 가져올 수 있습니까?

저는 LINQ를 사용하여 워크 플로의 현재 레코드를 검색하는 것이 좋습니다. 당신이 어떻게하고 있었는지에 문제가 없습니다. 아마도 Any()First() 대신 LINQ 확장 방법 FirstOrDefault()을 사용할 수 있습니다.

또한 일반적으로 Crm Retrieves가 필요한 열만 반환하는 것이 좋습니다. 하나의 레코드를 검색 할 때이를 알지 못할 수도 있지만 여러 레코드를 검색하는 경우이 작업을 반드시 수행해야합니다.

관련 문제