【问题标题】:Errors in my generic class when trying to pass an interface in the constructor尝试在构造函数中传递接口时,我的泛型类中的错误
【发布时间】:2019-09-26 00:35:57
【问题描述】:

在这里,我有 15 种以上调用 SOAP Web 服务的方法中的 2 种

       public async void CallWebServiceA() {
            var client = new WebServiceWRGClient();
            var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
            binding.MaxReceivedMessageSize = Int32.MaxValue;
            binding.MaxBufferSize = Int32.MaxValue;
            var endpoint = new EndpointAddress("https://trustonline.delawarecpf.com/tows/webservicewrg.svc"); 
            var channelFactory = new ChannelFactory<WebServiceWRG>(binding, endpoint);
            var webService = channelFactory.CreateChannel();
            var user = new GRACE_GRACES.User();
            user.UserName = await webService.EncryptValueAsync("username");
            user.Password = await webService.EncryptValueAsync("password12345");
            var response = await client.ClaimSearchAsync(user, "", "", 12345, GRACE_GRACES.statuscode.NotSet, "");
       }

       public async void CallWebServiceB() {
            var client = new WebServiceAWIClient();
            var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
            binding.MaxReceivedMessageSize = Int32.MaxValue;
            binding.MaxBufferSize = Int32.MaxValue;
            var endpoint = new EndpointAddress("https://trustonline.delawarecpf.com/tows/webserviceawi.svc"); 
            var channelFactory = new ChannelFactory<WebServiceAWI>(binding, endpoint);
            var webService = channelFactory.CreateChannel();
            var user = new ARM_ARMS.User();
            user.UserName = await webService.EncryptValueAsync("username");
            user.Password = await webService.EncryptValueAsync("password12345");
            var response = await client.ClaimSearchAsync(user, "", "", 12345, ARM_ARMS.statuscode.NotSet, "");
       }

我在下面创建了这个通用类,因此我不必为来自同一个提供程序的 15 多个 url/web 服务中的每一个创建多个冗余方法,但是我在传递第二个参数时遇到了一些错误,这是一个接口(来自 Web 服务参考)。

public class WebService<T1, T2, T3> {
    private T1 _client;
    private T2 _interface;
    private T3 _user;

    public WebService(T1 wsClient, T2 wsInterface, T3 wsUser) {
        _client = wsClient;
        _interface = wsInterface;
        _user = wsUser;
    }

    public void CallWebService(string url, string userName, string password) {
        var client = _client; 
        var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
        var endpoint = new EndpointAddress(url); 
        var channelFactory = new ChannelFactory<_interface>(binding, endpoint);  
        var webService = channelFactory.CreateChannel();
        var user = _user;
        user.UserName = webService.EncryptValue(userName);
        user.Password = webService.EncryptValue(password);
        var response = client.ClaimSearch(user, "", "", 12345, GraceStatuscode.NotSet, "");
    }

}

我在下面这样调用它,但是当我创建实例时在参数中或在创建 ChannelFactory 的新实例时在方法中无法识别接口 WebServiceWRG 和 WebServiceAWI。我得到一条红线,上面写着“找不到命名空间名称_interface的类型”,在我创建新类实例的那一行中,每个接口参数都有一条红线,上面写着“'WebServiceWRG'是一种类型,它不是在给定的上下文中有效”

WebService someServiceA = new WebService(new WebServiceWRGClient(), WebServiceWRG, new GRACE_GRACES.User());
WebService someServiceB = new WebService(new WebServiceAWIClient(), WebServiceAWI, new ARM_ARMS.User());

更新 这是我在下面尝试过的,但仍然有错误: user.UserName = webService.EncryptValue(userName); //Two不包含'UserName'的def,T不包含EncryptValue的def

   public class Test {
        public void TestWebService() {
            var ws = new WebService<WebServiceWRG>();
            ws.SearchClaim(new WebServiceWRGClient(), new GraceUser(), "url", "userName", "password");
        }
    }

    public class WebService<T> { 
        public void SearchClaim<TOne, TTwo>(TOne entity1, TTwo entity2, string url, string userName, string password) 
            where TOne : class
            where TTwo : class
        {
            var client = entity1;
            var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
            var endpoint = new EndpointAddress(url);
            var channelFactory = new ChannelFactory<T>(binding, endpoint);
            var webService = channelFactory.CreateChannel();
            var user = entity2;
            user.UserName = webService.EncryptValue(userName); // username not found, encryptvalue not found
            user.Password = webService.EncryptValue(password); // passwordnot found, encryptvalue not found
            var response = client.ClaimSearch(user, "", "", 12345, GraceStatuscode.NotSet, ""); // claimsearch not found
        }
    }

【问题讨论】:

  • 这不是泛型的问题,而是您调用WebService 的构造函数的方式的问题。 WebService 的构造函数需要三个参数。您将使用new 关键字创建的对象传递第一个和第三个参数值。第二个参数要作为接口名称传递。这就是它不起作用的方式。您需要传递一个实现接口WebServiceWRG 和/或WebServiceWRG 的类对象。
  • 使用的语法不正确。目前状态下的问题也是不完整的,因此不清楚。这可能是XY problem
  • 你能举个例子吗?
  • @user1186050 这段代码有很多语法问题,但如果没有你的指导,你实际上想做什么,就无法提供太多帮助。
  • 我正在将数据发送到在线服务/网络服务(我更新了帖子顶部的代码)以显示该方法。但是我有大约 15 个不同的 url,每个 url/web 服务都有它自己的引用,这些引用是由 .net 生成的。因此,每次我从 Web 服务调用“ClaimSearch()”时,我都必须使用不同的客户端、接口、用户来构造参数。其中每一项都来自不同的服务引用。

标签: c# generics interface


【解决方案1】:

让我们首先承认您所做的更改是正确的更改。避免代码重复很重要,可以显着提高代码质量。干得好!

这可能是朝着正确方向迈出的一步:

public class WebService<T1, T2, T3> {
    private T1 _client;
    private T3 _user;

    //No T2

    public WebService(T1 wsClient, T3 wsUser) {
        _client = wsClient;
        _user = wsUser;
        //No interface
    }

    public void CallWebService(string url, string userName, string password) {
        (...)
        var channelFactory = new ChannelFactory<T2>(binding, endpoint);   <---- use the T2 type
        (...)
    }
}

然后

var someServiceA = new WebService<WebServiceWRGClient, WebServiceWRG, Whatever_GRACE_GRACES_User()_returns_here>(new WebServiceWRGClient(), new GRACE_GRACES.User());

(请注意var,因为类型不是WebService而是WebService&lt;X,Y,Z&gt;


下一步

我认为您不需要为客户和用户使用泛型,下一步可能是:

public class WebService<T> {
    private Baseclassofallclients _client;
    private UserTypeHere _user;


    public WebService( Baseclassofallclients wsClient, UserTypeHere  wsUser) {
        _client = wsClient;
        _user = wsUser;
        //No interface
    }

    public void CallWebService(string url, string userName, string password) {
        (...)
        var channelFactory = new ChannelFactory<T>(binding, endpoint);   <---- use the T type here
        (...)
    }

然后

var someServiceA = new WebService<WebServiceWRG>(new WebServiceWRGClient(), new GRACE_GRACES.User());
var someServiceB = new WebService<WebServiceAWI>(new WebServiceAWIClient(), new ARM_ARMS.User());

【讨论】:

  • 嗨蒂姆塔姆。我不认为我理解您对“UserTypeHere”的使用,您能否解释一下这是什么以及它如何与示例一起使用?
  • Tymtam,我的每个 Users() 都来自每个不同的 Web 服务引用。
  • 我尝试了您的第一个示例,但它不起作用,因为该类仍然需要 3 个参数,而现在您只传递了 2 个
  • 什么类 .User() 返回 GRACE 和 ARM?
  • 你好 Tymtam。返回的 User() 类是从每个特定 Web 服务创建的命名空间中的部分类。所以我像这样引用命名空间: using GRACE_GRACES;然后像这样创建一个别名: using GraceUser = GRACE_GRACES.User;然后我会这样使用它: var user = new GRACE_GRACES.User();
猜你喜欢
  • 2017-09-17
  • 1970-01-01
  • 2010-10-16
  • 1970-01-01
  • 1970-01-01
  • 2016-05-18
  • 2022-12-05
相关资源
最近更新 更多