dimanche 21 février 2016

Providing configuration for a Class accepting multiple generic classes

I've been wrangling with this design and I think I'm trying to force a solution to a problem I'm creating with a poor design choice, but I'd like to get some external input.

Essentially, I have several concrete implementations of a class producing data, and a class consuming data, the data itself can be of various types. I would like a user to be able to choose an arbitrary producer of data, and list the corresponding compatible consumers (which accept the type of data provided by the producer). The data itself could be something as simple as an int or string every production cycle.

I've tried to flesh the simplified situation below. My issue comes when I actually try and think about instantiating an engine with a concrete consumer/producer. I've commented the below example, suggesting ideas I'm exploring.

As I'm typing this, it seems that the sensible solution would be to make all my producable/consumable types something like IData, a simple wrapper around the type which will be produced/consumed, but this seems like overkill, in that I'll likely be dealing with primitive types.

I'm sure there is a really simple solution, I might have been staring at it for too long.

Simplified example:

void Main()
{
    // Populated form concrete implementations in assembly.
    var producers = new List<IProducer>();
    var consumers = new List<IConsumer>();

    var engine = new Engine();

    // I'd like to allow the user to choose producer/consumer combinations.
    //engine.Configure();   

    engine.StartWork();
}

public class Engine
{
    public void Configure(IProducer producer, IConsumer consumer)   
    {   
        // Wire up Producer/Consumer, if types are compatible.
        // Simplified chain...
        // consumer.ConsumeSomething(producer.MakeSomething());
    }

    // Do this instead ?
    // Where is configure called from, does it know the types?
    // public void Configure<T>(IProducer<T> producer, IConsumer<T> consumer) {}

    public void StartWork() {}
}

// Instantiate an engine for all concrete producer/consumer types and present the user with a list of engines?
//public class Engine<T> {}

public interface IProducer<T> : IProducer
{
    T MakeSomething();
}

public interface IProducer
{
    // Non Generic producer methods/properties
}

public interface IConsumer<T> : IConsumer
{
    // Some Side effect, or return result.
    void ConsumeSomething(T input);
    //bool ConsumeSomething(T input);
}

public interface IConsumer
{
    // Non Generic consumer methods/properties.
}

Aucun commentaire:

Enregistrer un commentaire