2017-10-26 11 views
1

私のプロジェクトでは、いくつかのリクエストなどで使用されるカスタムエンティティのハンドラがあります。このハンドラ/エンティティは多くのプラグイン/ロガー/トレーサなどで参照されています。ユーザーを呼び出すのではなく、管理者のコンテキストでまた、admin guidの上に作成されたサービスを渡す代わりに、次のようになります。プラグイン内部Dynamics 365 - IOrganizationServiceを使用してOrganizationServiceProxyを作成する

----- -----

IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); 

var adminOrganizationService = factory.CreateOrganizationService(Guid.Parse("~ADMINGUID~")); 

MyEntityHandler myEntityHandler = new MyEntityHandler(adminOrganizationService); 

// Use myEntityHandler 

// What i do want to do is, calling my entity handler with the service of calling user , which looks like; 

MyEntityHandler myEntityHandler = new MyEntityHandler(factory.CreateOrganizationService(context.UserId)); 

// Use myEntityHandler 

と私のエンティティハンドラ内、OrganizationServiceProxyへの引数として渡されたサービスを変換し、admin GUIDにその発信者番号を変更したり、単に変更OrganizationServiceProxyに最初にキャストすることによって、IOrganizationService "サービス"のCallerID。ハンドラ内

-----は-----

private IOrganizationService service; 

public MyEntityHandler(IOrganizationService organizationService) 

{ 
      // This is what i have tried. 
      service = organizationService; 
      (service as OrganizationServiceProxy).CallerId = Guid.Parse("~ADMINGUID~"); 
} 

私が手に '例外:System.NullReferenceException:オブジェクト参照がオブジェクトインスタンスに設定されていません。'鋳造部分にある。 これは基本的に、このようなことをする方法があります。私は自分自身を十分に説明してくれてありがとうと思います...

答えて

1

プラグインに渡されるオブジェクトは、いくつかの外部のアプリケーションではなく、プラグインで使用されているOrganizationServiceProxyではないので、これは単純に機能していません。プラグインのオブジェクトは分離モードに基づいて異なります。非分離モードの場合はMicrosoft.Xrm.Extensibility.InprocessProxyService、サンドボックスモードの場合はMicrosoft.Crm.Sandbox.SandboxOrganizationServiceWrapperです。これらのタイプはどちらもSDKにはないので、リフレクションだけでそのプロパティにアクセスできます。最初のものはCallerIdプロパティを持っているので、リフレクションを使用してアクセスできるはずですが、2番目のプロパティはアクセスできません。したがって、この呼び出し元IDを置き換えることはできません。

有効な唯一のアプローチは、IOrganizationServiceの代わりにIOrganizationServiceFactoryをハンドラに渡してから、必要に応じてIOrganizationServiceを作成することです。あなたがプロジェクト全体の構造を変更したくない場合(私は最良のアプローチだと信じていますが、人々がリファクタリングを恐れていることを知っています。理由がないので、後で書き直さなければならない不器用なプロジェクトになります。そのようなメンテナンスの数年)は、IOrganizationServiceFactoryをパラメータとするハンドラ用の2番目のコンストラクタを作成するだけです。これにより、既存のコードがそのまま維持され、管理者サービスと管理者以外のサービスの両方を使用する必要があるハンドラでは、 2番目のコンストラクタです。

public class MyHandler 
{ 
    private IOrganizationService service; 
    private IOrganizationService adminService; 

    public MyHandler(IOrganizationService service) 
    { 
     this.service = service; 
    } 

    public MyHandler(IOrganizationServiceFactory factory, Guid userId) //instead of passing userId here, it would be better to pass it to the method that you want to perform 
    { 
     this.service = factory.CreateOrganizationService(userId); 
     this.adminService = factory.CreateOrganizationService(null); 
    } 
} 

それとも単にその方法:

public class MyHandler 
{ 
    private IOrganizationService service; 
    private IOrganizationService adminService; 

    public MyHandler(IOrganizationService service) 
    { 
     this.service = service; 
    } 

    public MyHandler(IOrganizationService service, IOrganizationService adminService) : this(service) 
    { 
     this.adminService = adminService; 
    } 
} 

これは単に一例であり、もちろん私はあなたのアーキテクチャについて多くを知らないが、確かなアプローチのために多くの、より良いクリーナーとに容易になるだろうあなたが今何をしようとしているのかを将来的に維持してください。いい理由はありませんが、コードをリファクタリングすることを恐れることはありません。)

+0

あなたの助けに感謝、私はこのトピックについてのあなたの視点を検討します。 –

0

CreateOrganizationServiceの間にシステムユーザーを工場に偽装できるように、nullを渡すことができます。

// Use the factory to generate the Organization  
Service.OrganizationServiceImpersonated = factory.CreateOrganizationService(null); 

Read more

+0

まずはお返事ありがとうございます。もし私が間違っていれば私を許してください。あなたの提案はserviceProviderまたは工場を使って偽装サービスを作成することですが、実際には私ができることを探しています私のハンドラは、すべてのプロジェクト構造を変更しないようにする必要があります。 –

+0

は、((OrganizationServiceProxy)this.serviceのような)何かを試すことができます.CallerId = new Guid( "AdminGUID"); –

+0

いいえ、試しましたが、それは働いていません。隔離モードでこの操作が制限される可能性がありますか?私はダイナミクス365を使用しているので、サンドボックスモードがオンになっています。 –

関連する問題