2017-02-05 6 views
1

"OperationContract"操作を含む "ServiceContract"を使用している場合。 オペレーションは、戻り値または受信されたインターフェイスパラメータです。 サービスを使用しているときに例外メッセージが表示される:WCFの "KnownType"属性を持たないインターフェイスデータ型の使用方法は?

"デシリアライザでは、この名前にマップされている型は認識されていません。DataContractSerializerを使用している場合は、 %className%} 'を既知の型のリストに追加します。

KnowTypesの属性をインターフェイスに追加することはできますが、私のインターフェイスプロジェクトは実装プロジェクトから切り離されており、循環依存関係を持つことができないため、KnowTypesを宣言することはできません。

最適なソリューションは何ですか?

+0

あなたが再設計する必要があるようなサウンドです。あなたのインターフェイスプロジェクトは実装に依存してはいけません。 – Crowcoder

+0

これは私が避けようとしていることです。私のデザインは、インターフェイスと実装の分離を持っているので、インターフェイス上でKnownTypes属性を使用することはできません。 –

答えて

0

私は解決策を見つけました。

ServiceKnownTypeを実装するタイプをロードするServiceKnownTypeを使用しています(DataContractメンバー用)。例えば

私は動物のインタフェースを持っている:

public interface IAnimal 
{ 
    string Name { get; } 

    void MakeSound(); 
} 

と実装(インターフェース実装タイプを知りません):

public class Cat : IAnimal 
{ 
    public string Name =>"Kitty"; 

    public void MakeSound() 
    { 
     Console.WriteLine("Meeeee-ow!"); 
    } 
} 

    public class Dog : IAnimal 
    { 
     public string Name => "Lucy"; 

     public void MakeSound() 
     { 
      Console.WriteLine("Wolf Wolf!"); 
     } 
    } 

CatDogタイプを使用するためのものサービス内にIAnimalインターフェイスを実装します。

public interface IAnimalService: IAnimalService 
{ 
    IAnimal GetDog(); 
    void InsertCat(IAnimal cat); 
} 

インターフェイスタイプによってタイプをロードする属性ServiceKnownTypeを使用できます。

私はすべてのIAnimal種類返す静的クラス作成:

public static class AnimalsTypeProvider 
{ 
    public static IEnumerable<Type> GetAnimalsTypes(ICustomAttributeProvider provider) 
    { 
     //Get all types that implement animals. 
     //If there is more interfaces or abtract types that been used in the service can be called for each type and union result    
     IEnumerable<Type> typesThatImplementIAnimal = GetAllTypesThatImplementInterface<IAnimal>(); 

     return typesThatImplementIAnimal; 
    } 

    public static IEnumerable<Type> GetAllTypesThatImplementInterface<T>() 
    { 
     Type interfaceType = typeof(T); 
     //get all aseembly in current application 
     var assemblies = AppDomain.CurrentDomain.GetAssemblies(); 
     List<Type> typeList = new List<Type>(); 
     //get all types from assemblies 
     assemblies.ToList().ForEach(a => a.GetTypes().ToList().ForEach(t => typeList.Add(t))); 

     //Get only types that implement the IAnimal interface 
     var alltypesThaImplementTarget = 
      typeList.Where(t => (false == t.IsAbstract) && t.IsClass && interfaceType.IsAssignableFrom(t)); 


     return alltypesThaImplementTarget; 
    }   
} 

およびサービス・インターフェース属性にクラスAnnimalsTypeProviderとメソッドGetAnimalsTypesを追加する:

[ServiceContract] 
[ServiceKnownType("GetAnimalsTypes", typeof(AnimalsTypeProvider))] 
public interface IServicesServer : IAnimalService 
{ 
    IAnimal GetDog(); 
    void InsertCat(IAnimal cat); 
} 

をし、それはそれです!

サービスをロードしているときに、既知のタイプのすべてのタイプが動的モードでロードされます。構成はまったくなく、CatDogになります。

関連する問題