How to use interface data type without attribute "KnownType" in WCF?

If I use "ServiceContract", which contains the operation "OperationContract". The operation returns or accepts interface parameters. When I use the service, I get an error message:

"Deserializer does not know any type that maps to this name. Consider using DataContractResolver if you are using DataContractSerializer or add a type corresponding to" {% className%} "in the list of known types."

I can add the KnowTypes attribute to the interface, but my interface project is separate from the implementation project, and they cannot have a loop dependency link, so KnowTypes cannot be declared.

What is the best solution?

+1
source share
2 answers

Unfortunately this is not possible. A similar question has already been asked: Using Interfaces with WCF

0
source

I found a solution and it worked!

I use ServiceKnownTypethat load types that members implement ServiceKnownTypefor DataContract.

For instance:

I have an interface for animals:

public interface IAnimal
{
    string Name { get; }

    void MakeSound();
}

and implementation (the interface does not know the types of implementation):

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!");
        }
    }

To use the types Catand Dogthat implement the interface IAnimalin the service:

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

I can use an attribute ServiceKnownTypethat will load the type by interface type.

I Created a static class that returns all types 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);
 }

!

IAnimal Cat Dog - .

0

Source: https://habr.com/ru/post/1775130/


All Articles