Dynamics 365-使用IOrganizationService创建OrganizationServiceProxy [英] Dynamics 365 - Create OrganizationServiceProxy using IOrganizationService

查看:155
本文介绍了Dynamics 365-使用IOrganizationService创建OrganizationServiceProxy的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用于自定义实体的处理程序类(此处处理了一些sdk请求),并且在许多插件/类中都引用了该处理程序。必须通过管理上下文访问此实体,而不是调用用户。我们没有将通过admin guid创建的服务传递给处理程序类,而是尝试在处理程序类内部模拟服务。例如;

I have a handler class (some sdk requests are handled here) for a custom entity and this handler is referenced in many plugins/classes. This entity must be reached over admin context instead of calling user. Instead of passing the service "that is created over admin guid" to the handler class, we are trying to impersonate the service inside the handler class. For example;

-----在插件内部-----

----- Inside the Plugin -----

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

// Instead of doing something like this;
var adminOrganizationService = factory.CreateOrganizationService(Guid.Parse("~ADMINGUID~"));
MyEntityHandler myEntityHandler = new MyEntityHandler(adminOrganizationService);
// Use myEntityHandler

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

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

并在我的实体处理程序中,更改IOrganizationService实例的CallerID首先将其转换为OrganizationServiceProxy。

and inside my entity handler, change the CallerID of the IOrganizationService instance by casting it to the OrganizationServiceProxy first.

-----在处理程序内部-----

----- Inside the Handler -----

private IOrganizationService service;

public MyEntityHandler(IOrganizationService organizationService)

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






我得到异常: System.NullReferenceException:对象参考未设置为铸造零件中的对象实例。
有没有办法做这样的事情。我希望我对自己的解释足够好,谢谢...


I get 'Exception: System.NullReferenceException: Object reference not set to an instance of an object.' in the casting part. Is there any way to do something like this. I hope i explained myself well enough, thanks...

推荐答案

这不仅仅因为传递给对象的对象而起作用插件不是 OrganizationServiceProxy ,它在某些外部应用程序中使用,但在插件中未使用。插件中的对象根据隔离模式而有所不同,据我所记得,对于非隔离模式,它是 Microsoft.Xrm.Extensibility.InprocessProxyService ;对于沙盒模式,它是 Microsoft.Crm.Sandbox.SandboxOrganizationServiceWrapper 。这两种类型都不在SDK中,因此您只能通过反射来访问它们的属性。第一个具有CallerId属性,因此您应该可以使用反射来访问它,但是第二个则不能,因此我认为不可能替换此呼叫者ID。

This is not working simply because the object that is passed to the plugin is not OrganizationServiceProxy which is used in some external apps but not in the plugins. The object in plugins is different based on the isolation mode, as far as I remember for not-isolated mode it is Microsoft.Xrm.Extensibility.InprocessProxyService and for Sandbox mode it is Microsoft.Crm.Sandbox.SandboxOrganizationServiceWrapper. Both of these types are not in SDK, so you can access their properties only with reflection. The first one has CallerId property, so you should be able to access it using reflection, but the second one does not, so I don't think it's possible to replace this caller id.

唯一应该采取的有效方法是将 IOrganizationServiceFactory 传递给处理程序,而不是 IOrganizationService ,然后根据您的需要创建 IOrganizationService 。如果您不想更改整个项目的结构(我认为这是最好的方法,但是我已经知道人们会出于无理由而害怕重构,而我们最终会陷入笨拙的项目中,之后必须重新编写)几年的维护)只需为您的处理程序创建第二个构造函数,该构造函数将使用 IOrganizationServiceFactory 作为参数-这将使您现有的代码保持完整,并保留在需要处理的处理程序中

The only valid approach that you should take is to pass IOrganizationServiceFactory to your handlers instead of IOrganizationService and then create IOrganizationService based on your needs. If you don't want to change your whole project structure (which I believe would be the best approach, but I already know that people are afraid of refactoring, for no good reason, and we end up in clumsy projects that have to rewritten after few years of such maintenance) just create a second constructor for your handler which will take IOrganizationServiceFactory as a parameter - this would keep your existing code intact and in handlers for which you need to use both admin and not-admin services, you will simply use the second constructor.

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;
    }
}

这只是示例,我当然不对您的体系结构了解很多,但是可以肯定的是,这种方法将来会比现在要尝试的方法更好,更清洁,更容易维护(出于没有充分的理由,请再次注意-不要害怕重构代码) ,大部分工作都会为您执行Visual Studio ...)

This is simply the example, of course I do not know much about your architecture, but for sure such approach would be much better, cleaner and easier to maintain in the future then what you are trying to do right now (for no good reason, again - don't be afraid of refactoring the code, most of the work would do Visual Studio for you...)

这篇关于Dynamics 365-使用IOrganizationService创建OrganizationServiceProxy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆