Is there any way to implement an interface in a class of a DLL that I can only read?

Asked

Viewed 200 times

2

I am using a DLL that has several classes. I would like to dynamically implement interfaces for these classes, so that I can perform unit tests by making a mock of the same.

Is there any way to do that?

Example:

The DLL has a class Comunicador

public class Comunicador
{
    public void Executar()
    {
        //executa
    }
}

Is there any way I can get this class to implement the interface below dynamically?

public interface IComunicador
{
    void Executar();
}

That way, I want a property

public IComunicador Comunicador { get; set; }

Can you understand the following:

Comunicador = new Comunicador();

2 answers

4

Even C# 7 is not possible. Even when you can there will be restrictions, not yet fully defined, of what you can do.

To test has how to access the method if you know that it is implemented, it is not ideal, but it is possible to force the test.

Not only for testing, but for use in production it is possible to create a design pattern that helps to deal with this, although it is not ideal either, but it may be the only way. Probably a Adapter. In the case described in the question would not even need to implement anything, just have another object that has the interface and that delegates to what already exists.

Note that you can only access what is public in this adapter. You can never access something private, except for reflection, which would be a huge gambit creating maintenance risks.

I do not know if it is the best alternative to the question, but it is one of them. There are other patterns that may help.

The solution given by Rovann Linhalis is probably more appropriate.

I consider that gambiarra, but in legacy gambiarras code are necessary.

I found it curious if you mention TDD of something that already exists.

  • It would not be the case to use MEF

  • It is legacy yes, but as I am implementing new code by TDD I ended up quoting erroneously. The problem of calling this class that is public is that it has called a database, which I cannot do in my unit test. I’ll check the Adapter to see if he’ll pick up, thank you! (And yes, I wouldn’t go so far as to use Reflection just to create such a test)

  • @Grupocdsinformática I don’t think so. MEF is for something else.

3


And if you created a class MeuComunicador just to implement the interface, would solve your problem?

Example:

using System;

public class Program
{
    public static void Main()
    {
        MinhaClasse obj = new MinhaClasse();

        obj.ObjComunicador = new MeuComunicador();
        obj.ObjComunicador.Executar();
        Console.WriteLine("Fim");
    }
}


public class MinhaClasse
{
    public IComunicador ObjComunicador   {get;set;}
}


public class Comunicador //Essa classe você não pode mexer né ?!
{
    public void Executar()
    {
        //supondo que o metodo do comunicador original faça algo...
        Console.WriteLine("Executando método do comunicador ... ");
    }
}

public class MeuComunicador : Comunicador, IComunicador
{

}

public interface IComunicador
{
    void Executar();
}

Upshot:

Running the communicator method ...

End

I tested on . Netfiddle: https://dotnetfiddle.net/9AwVEA

  • 1

    I think as there is already enough legacy code implemented this is the most viable solution for now. Adding a project pattern as mentioned by @Maniero would be tricky at this point. I will test and give back.

  • 1

    Thank you! This solution solves my problem.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.