我们正在从 Dynamics On-Prem 迁移到 Dynamics 365 online。因此,我们还必须更改连接到 Dynamics 的 Web 应用程序。
Web 应用程序仍在运行,但性能很差。我们开始做一些跟踪,看看为什么。在此跟踪中,我们看到该应用程序正在为单个请求执行对 Dynamics online 的不同调用。这样做的原因是我们确实在检索不同的数据集。但是我们惊讶地看到身份验证也进行了多次。这种身份验证减慢了动态响应。我们期望仅对第一个请求进行身份验证。
我用来建立连接的代码位于一个抽象类中,该类由不同的其他类实例化。此类使用以下属性从命名空间 Microsoft.Xrm.Tooling.Connector 返回 CrmServiceClient:
protected CrmServiceClient CustomCrmServiceProxy
{
get
{
CrmServiceClient client = new CrmServiceClient(CrmConnection.Connectionstring);
client.CallerId = GetCallerId();
return client;
}
}
连接字符串是 AuthType=ClientSecret;url={0};ClientId={1};ClientSecret={2};替换值。
在使用抽象类的类中,我们像这样调用属性
var data = this.CustomCrmServiceProxy.RetrieveMultiple("fetch xml");
重要是我们将调用者id传递给CrmServiceClient,当访问者切换到另一种语言的页面时,这个调用者可能会有所不同。
有没有办法防止多重身份验证? 实现单例模式是一种选择吗?但是在这种情况下,不同的 callerid 怎么办? CrmServiceClient 可能有一个很好的例子吗?
答案 0 :(得分:0)
你能试试这样的吗?
这将创建连接的单个实例(带有调用者 ID),然后持续引用该实例。
CrmServiceClient _client = null;
protected CrmServiceClient CustomCrmServiceProxy
{
get
{
if (_client == null)
{
_client = new CrmServiceClient(CrmConnection.Connectionstring);
_client.CallerId = GetCallerId();
}
return _client;
}
答案 1 :(得分:0)
CrmServiceClient
提供了许多构造函数,提供了重用连接实例的机会。
例如以下构造函数重载具有参数 useUniqueInstance
。当应使用缓存实例时,将 false
值传递给它。
public CrmServiceClient(string userId, SecureString password, string domain, string homeRealm, string hostName, string port, string orgName, bool useUniqueInstance = false, bool useSsl = false, OrganizationDetail orgDetail = null)
然而,在大多数情况下,一个 Web 应用程序将被多个客户端使用,通常是并发的,并且在这些情况下,单例连接对象不能很好地扩展。在这些情况下,您可以引入连接池。
连接池类将负责维护 CrmServiceClient
实例的集合。工厂模式可用于从池对象中声明实例。处置后,工厂实例会将所有声明的实例返回到池中。
您的工厂类可以实现现有的 IOrganizationServiceFactory
。此界面的设计考虑到了模拟要求。
注意:不要让当前使用 CrmServiceClient
连接的类负责创建这些实例。而是将 IOrganizationServiceFactory
或 IOrganizationService
对象注入到这些类的构造函数中。
答案 2 :(得分:0)
我见过程序执行 get
访问器的次数比我想象的要多的情况。
与其将其作为属性,不如尝试将其变成一种方法。
protected CrmServiceClient GetService()
{
var client = new CrmServiceClient(CrmConnection.Connectionstring);
client.CallerId = GetCallerId();
return client;
}
然后,延迟实例化的一种选择是:
private CrmServiceClient _svc;
private CrmServiceClient svc => _svc ?? (_svc = GetService());