2010-06-30 14 views
8

में ऑब्जेक्ट मैं अपनी कॉन्फ़िगरेशन में एक ज्ञात प्रकार निर्दिष्ट करने की कोशिश कर रहा हूं, लेकिन मुझे इस तथ्य के साथ समस्याएं आ रही हैं कि यह ऑब्जेक्ट से प्राप्त होती है। मैं इसे विशेषता के माध्यम से ज्ञात प्रकार निर्दिष्ट करने के लिए काम कर सकते हैं। लेकिन इस मामले में मुझे इसे कॉन्फ़िगरेशन से काम करने की आवश्यकता है।डब्ल्यूसीएफ सिस्टम से ज्ञात प्रकार। कॉन्फ़िगर

यहां एक उदाहरण है। ठीक निम्नलिखित काम करता है:

[ServiceContract] 
[ServiceKnownType(typeof(MyData))] 
public interface IContract 
{ 
    [OperationContract] 
    void Send(object data); 
} 

[DataContract] 
public class MyData 
{ 
    [DataMember] 
    public string Message { get; set; } 
} 

लेकिन अगर मैं ServiceKnownType विशेषता को हटाने और config में निम्नलिखित डाल:

<system.runtime.serialization> 
    <dataContractSerializer> 
    <declaredTypes> 
     <add type="System.Object, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
     <knownType type="WpfApplication1.MyData, WpfApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/> 
     </add> 
    </declaredTypes> 
    </dataContractSerializer> 
</system.runtime.serialization> 

मैं "संदेश के साथ संपत्ति 'प्रकार' के लिए मूल्य एक ConfigurationErrorsException मिल मान्य नहीं है। त्रुटि यह है: प्रकार System.Object को घोषित प्रकार के रूप में कॉन्फ़िगर नहीं किया जा सकता है। "

क्या यह काम कॉन्फ़िगरेशन के माध्यम से करने के लिए वैसे भी है?

उत्तर

9

उत्तर यह है कि यह करना संभव नहीं है कि मैं केवल कॉन्फ़िगर फ़ाइल में क्या करना चाहता हूं। उपरोक्त कॉन्फ़िगरेशन DataContracts पर उपयोग की जाने वाली [KnownType] विशेषता से मेल खाता है। कॉन्फ़िगरेशन में [ServiceKnownType] को लागू करने का कोई तरीका नहीं प्रतीत होता है।

कस्टम कॉन्फ़िगरेशन अनुभाग के साथ [ServiceKnownType (methodName, type)] विशेषता का उपयोग करने के लिए एक वैकल्पिक दृष्टिकोण है। नई config इस तरह दिखता है:

<configuration> 
    <configSections> 
    <section 
     name="serviceKnownTypes" 
     type="WpfApplication1.ServiceKnownTypesSection, WpfApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/> 
    </configSections> 
    <serviceKnownTypes> 
    <declaredServices> 
     <serviceContract type="WpfApplication1.IContract, WpfApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"> 
     <knownTypes> 
      <knownType type="WpfApplication1.MyData, WpfApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/> 
     </knownTypes> 
     </serviceContract> 
    </declaredServices> 
    </serviceKnownTypes> 
</configuration> 

अनुबंध:

[ServiceContract] 
[ServiceKnownType("GetServiceKnownTypes", typeof(KnownTypeHelper))] 
public interface IContract 
{ 
    [OperationContract] 
    void Send(object data); 
} 

[DataContract] 
public class MyData 
{ 
    [DataMember] 
    public string Message { get; set; } 
} 

सहायक वर्ग कि कॉलबैक कि ज्ञात प्रकार

public static class KnownTypeHelper 
{ 
    public static IEnumerable<Type> GetServiceKnownTypes(ICustomAttributeProvider provider) 
    { 
     List<Type> result = new List<Type>(); 

     ServiceKnownTypesSection serviceKnownTypes = (ServiceKnownTypesSection)ConfigurationManager.GetSection("serviceKnownTypes"); 
     DeclaredServiceElement service = serviceKnownTypes.Services[((Type)(provider)).AssemblyQualifiedName]; 

     foreach (ServiceKnownTypeElement knownType in service.KnownTypes) 
     { 
      result.Add(knownType.Type); 
     } 

     return result; 
    } 
} 

सूचना की सूची देता है कस्टम config बनाने पर होता है अनुभाग यहां पाए जा सकते हैं:

http://msdn.microsoft.com/en-us/library/2tw134k3.aspx

http://msdn.microsoft.com/en-us/library/system.configuration.configurationcollectionattribute.aspx

2

मुझे यकीन है कि अगर यह डिजाइन के द्वारा होता है, लेकिन अगर आप ज्ञात प्रकार के साथ एक सेवा अनुबंध घोषित नहीं किया गया है KnownTypeHelper नीचे एक त्रुटि फेंक नहीं होगा नहीं कर रहा हूँ। (यानी सेवा अनुबंधों में ज्ञात प्रकार जोड़ने के लिए यह वैकल्पिक है)।

using System; 
using System.Collections.Generic; 
using System.Configuration; 
using System.Reflection; 

/// <summary> 
/// Helper for finding the known types for Wcf Services from a configuration file. 
/// </summary> 
public static class KnownTypeHelper 
{ 
    /// <summary> 
    /// Gets the known types for the service from a configuration file. 
    /// </summary> 
    /// <param name="provider"> 
    /// The provider. 
    /// </param> 
    /// <returns> 
    /// The known types for the service from a configuration file. 
    /// </returns> 
    public static IEnumerable<Type> GetServiceKnownTypes(ICustomAttributeProvider provider) 
    { 
     var result = new List<Type>(); 

     var serviceKnownTypes = (ServiceKnownTypesSection)ConfigurationManager.GetSection("serviceKnownTypes"); 
     if (serviceKnownTypes != null) 
     { 
      var service = serviceKnownTypes.Services[((Type)provider).AssemblyQualifiedName]; 

      if (service != null) 
      { 
       foreach (ServiceKnownTypeElement knownType in service.KnownTypes) 
       { 
        result.Add(knownType.Type); 
       } 
      } 
     } 

     return result; 
    } 
} 

किसी और विन्यास कक्षाएं बनाने की मुसीबत बचाने के लिए,

नोट: विधानसभा योग्य प्रकार नाम की कोई मान्यता नहीं है। अगर कोई ऐसा करने के लिए एप्रोपिएट विशेषताओं को जोड़ना चाहता है, तो कृपया करें।

using System.Configuration; 

/// <summary> 
/// Section for configuration known types for services. 
/// </summary> 
public class ServiceKnownTypesSection : ConfigurationSection 
{ 
    /// <summary> 
    /// Gets services. 
    /// </summary> 
    [ConfigurationProperty("declaredServices", IsDefaultCollection = false)] 
    [ConfigurationCollection(typeof(DeclaredServiceElement), AddItemName = "serviceContract", CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)] 
    public DeclaredServiceElementCollection Services 
    { 
     get 
     { 
      return (DeclaredServiceElementCollection)base["declaredServices"]; 
     } 
    } 
} 

/// <summary> 
/// Collection of declared service elements. 
/// </summary> 
public class DeclaredServiceElementCollection : ConfigurationElementCollection 
{ 
    /// <summary> 
    /// Gets the service for which known types have been declared for. 
    /// </summary> 
    /// <param name="key"> 
    /// The key of the service. 
    /// </param> 
    public new DeclaredServiceElement this[string key] 
    { 
     get 
     { 
      return (DeclaredServiceElement)BaseGet(key); 
     } 

     set 
     { 
      var element = BaseGet(key); 
      var index = this.BaseIndexOf(element); 
      if (BaseGet(index) != null) 
      { 
       BaseRemoveAt(index); 
      } 

      BaseAdd(index, value); 
     } 
    } 

    /// <summary> 
    /// When overridden in a derived class, creates a new <see cref="T:System.Configuration.ConfigurationElement"/>. 
    /// </summary> 
    /// <returns> 
    /// A new <see cref="T:System.Configuration.ConfigurationElement"/>. 
    /// </returns> 
    protected override ConfigurationElement CreateNewElement() 
    { 
     return new DeclaredServiceElement(); 
    } 

    /// <summary> 
    /// Gets the element key for a specified configuration element when overridden in a derived class. 
    /// </summary> 
    /// <returns> 
    /// An <see cref="T:System.Object"/> that acts as the key for the specified <see cref="T:System.Configuration.ConfigurationElement"/>. 
    /// </returns> 
    /// <param name="element"> 
    /// The <see cref="T:System.Configuration.ConfigurationElement"/> to return the key for. 
    /// </param> 
    protected override object GetElementKey(ConfigurationElement element) 
    { 
     return ((DeclaredServiceElement)element).Type; 
    } 
} 

/// <summary> 
/// The service for which known types are being declared for. 
/// </summary> 
public class DeclaredServiceElement : ConfigurationElement 
{ 
    /// <summary> 
    /// Gets or sets Type. 
    /// </summary> 
    [ConfigurationProperty("type", IsRequired = true, IsKey = true)] 
    public string Type 
    { 
     get 
     { 
      return (string) this["type"]; 
     } 

     set 
     { 
      this["type"] = value; 
     } 
    } 

    /// <summary> 
    /// Gets KnownTypes. 
    /// </summary> 
    [ConfigurationProperty("knownTypes", IsDefaultCollection = false)] 
    [ConfigurationCollection(typeof(DeclaredServiceElement), AddItemName = "knownType", CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)] 
    public ServiceKnownTypeElementCollection KnownTypes 
    { 
     get 
     { 
      return (ServiceKnownTypeElementCollection)base["knownTypes"]; 
     } 
    } 
} 

/// <summary> 
/// A collection of known type elements. 
/// </summary> 
public class ServiceKnownTypeElementCollection : ConfigurationElementCollection 
{ 
    /// <summary> 
    /// Gets an known type with the specified key. 
    /// </summary> 
    /// <param name="key"> 
    /// The key of the known type. 
    /// </param> 
    public new ServiceKnownTypeElement this[string key] 
    { 
     get 
     { 
      return (ServiceKnownTypeElement)BaseGet(key); 
     } 

     set 
     { 
      var element = BaseGet(key); 
      var index = this.BaseIndexOf(element); 
      if (BaseGet(index) != null) 
      { 
       BaseRemoveAt(index); 
      } 

      BaseAdd(index, value); 
     } 
    } 

    /// <summary> 
    /// When overridden in a derived class, creates a new <see cref="T:System.Configuration.ConfigurationElement"/>. 
    /// </summary> 
    /// <returns> 
    /// A new <see cref="T:System.Configuration.ConfigurationElement"/>. 
    /// </returns> 
    protected override ConfigurationElement CreateNewElement() 
    { 
     return new ServiceKnownTypeElement(); 
    } 

    /// <summary> 
    /// Gets the element key for a specified configuration element when overridden in a derived class. 
    /// </summary> 
    /// <returns> 
    /// An <see cref="T:System.Object"/> that acts as the key for the specified <see cref="T:System.Configuration.ConfigurationElement"/>. 
    /// </returns> 
    /// <param name="element"> 
    /// The <see cref="T:System.Configuration.ConfigurationElement"/> to return the key for. 
    /// </param> 
    protected override object GetElementKey(ConfigurationElement element) 
    { 
     return ((ServiceKnownTypeElement)element).Type; 
    } 
} 

/// <summary> 
/// Configuration element for a known type to associate with a service. 
/// </summary> 
public class ServiceKnownTypeElement : ConfigurationElement 
{ 
    /// <summary> 
    /// Gets or sets TypeString. 
    /// </summary> 
    [ConfigurationProperty("type", IsRequired = true, IsKey = true)] 
    public string TypeString 
    { 
     get 
     { 
      return (string)this["type"]; 
     } 

     set 
     { 
      this["type"] = value; 
     } 
    } 

    /// <summary> 
    /// Gets or sets Type. 
    /// </summary> 
    public Type Type 
    { 
     get 
     { 
      return Type.GetType(this.TypeString); 
     } 

     set 
     { 
      this["type"] = value.AssemblyQualifiedName; 
     } 
    } 
} 
संबंधित मुद्दे