.NET类属性更改的范围是什么

本文关键字:范围 范围是 是什么 属性 NET | 更新日期: 2023-09-27 18:20:29

我正在尝试使用.NET中的第三方SOAP API。像往常一样,我生成了一个C#代理类来调用它,一切都很好。

然后,我与供应商进行了交谈,发现为了在租户(数据库)之间切换,我必须指定一个不同的XML名称空间。问题是,名称空间被烘焙到代理代码中。匿名版本:

[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
[System.Web.Services.WebServiceBindingAttribute(
    Name="eStrangeAPI", Namespace="urn:wsTenantSpecific")]
public partial class eTimeWSService : System.Web.Services.Protocols.SoapHttpClientProtocol {
    [System.Web.Services.Protocols.SoapDocumentMethodAttribute("", 
        RequestNamespace="urn:wsTenantSpecific:eStrange",
        ResponseNamespace="urn:wsClientSpecificNamespace:eStrange", ...]
    ...
    public string methodCall(ref Param param) {
        ...
    }

因此,我需要根据当前使用的帐户更改wsTenantSpecific名称空间。我可以获取类上的属性并动态修改它们。。。

var attr = ((WebServiceBindingAttribute[])
    typeof( eTimeWSService ).GetCustomAttributes(
    typeof( WebServiceBindingAttribute ), false ))[ 0 ];
attr.Namespace = "urn:wsADifferentNameSpace";

但我担心这有多线程安全。我们可以同时连接多个帐户,在同一进程中的不同线程上运行ASP.NET请求。

底线问题:如果我更改了一个属性,它是为整个进程更改还是仅为当前线程更改?

.NET类属性更改的范围是什么

底线问题:如果我更改了一个属性,它是为整个进程更改还是仅为当前线程更改?

两者都没有。两者兼而有之。这取决于情况。

在有人请求之前,属性对象实际上并不存在,即使这样,也不能保证每次请求时都会得到相同的实例,因此更改属性上的值很可能对另一个检查该属性的调用者没有任何影响。然而,在某些情况下,属性实例可能会被缓存,在这种情况下,可能会获得相同的实例,因此这可能很重要。但是当谈到序列化程序和类似的工具时,很有可能使用了元编程和缓存策略,所以它实际上并不是每次都检查属性——事实上,它很可能在第一次需要时就发出了一些动态代码,现在根本不打算重新访问反射方面。

我个人会寻找另一种方法。改变属性不是一个很好的方法。

例如,写入hello/hello(更改丢失):

using System;
class FooAttribute : Attribute {
    public FooAttribute(string bar) {
        Bar = bar;
    }
    public string Bar { get; set; }
}
[Foo("hello")]
class Program {
    static void Main() {
        WriteFooBar<Program>();
        var d = (FooAttribute)Attribute.GetCustomAttribute(
            typeof(Program), typeof(FooAttribute));
        d.Bar = "world";
        WriteFooBar<Program>();
    }
    static void WriteFooBar<T>() {
        var bar = ((FooAttribute)Attribute.GetCustomAttribute(
            typeof(T), typeof(FooAttribute))).Bar;
        Console.WriteLine(bar);
    }
}

这个类似的代码写hello/world(更改被保留):

using System;
using System.ComponentModel;
class FooAttribute : Attribute {
    public FooAttribute(string bar) {
        Bar = bar;
    }
    public string Bar { get; set; }
}
[Foo("hello")]
class Program {
    static void Main() {
        WriteFooBar<Program>();
        var d = (FooAttribute)TypeDescriptor.GetAttributes(typeof(Program))[
            typeof(FooAttribute)];
        d.Bar = "world";
        WriteFooBar<Program>();
    }
    static void WriteFooBar<T>() {
        var bar = ((FooAttribute)TypeDescriptor.GetAttributes(typeof(Program))[
            typeof(FooAttribute)]).Bar;
        Console.WriteLine(bar);
    }
}

(因为TypeDescriptor.GetAttributes缓存每个类型的实际属性实例,其中Attribute.GetCustomAttribute为每个调用创建新实例)

我认为这里最好的方法不是使用代理类,而是将SOAP请求发送到服务器,这样就可以完全控制要分别向服务器发送和从服务器接收的xml。

使用HttpWebRequest和WebResponse类来控制soap请求。根据您的逻辑更改命名空间(xmlns:xsi)。。

对于e,g,:-

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
      Your Request goes here....
  </soap:Body>
</soap:Envelope>

请参阅无代理web服务客户端

相关文章: