Question

I'm currently developing a small component-based framework the Android platform. The framework has some ready for use and some abstract (has some internal logic, but the developer needs to add some code to make it fully functional) components. All communication between the components is satisfied using interfaces. My question is:

Knowing that some components have dependencies, my framework should automatically provide them?

E.g.: I have an A component that "needs" B component. At first, I thought of two solutions:

  1. My framework should create and inject the B component automatically when the developer instantiate the component A. If B is an abstract component, I would create and provide a default instance of it.

  2. The framework should explain in the API that A component needs B component and then, leave to the developer to instantiate B component and pass it as a dependency to A.

In the second solution the developer could also create a new component that respects the contract (interfaces) with the A component and then use it.

Which of these solutions would lead to better maintenance, flexibility, and expansion of both the framework and the developers code? I accept other solutions.

Était-ce utile?

La solution

Do both

If you are making a framework, flexibility is key. Most frameworks provide interfaces and default implementations along with empty constructors wired to defaults, but allow for you to overwrite behavior by passing in your own implementations, or passing in a framework-provided alternative implementation.

public interface IReader { string Read(); }
public interface IWriter { void Write(String str); }

public class DefaultReader: IReader
{
    public string Read()
    {
        File.ReadAll("c:\myfile.cnf");
    }
}

public class DefaultWriter: IWriter
{
    public void Write(String str)
    {
        File.Write("c:\myfile.cnf", str);
    }
}

public class MyFrameWorkClass
{
    private IReader reader;
    private IWriter writer;

    public MyFrameWorkClass():
        this(new DefaultReader(), new DefaultWriter())
    {
    }

    public MyFrameWorkClass(IReader reader, IWriter writer)
    {
        this.reader = reader;
        this.writer = writer;
    }
}

The reason frameworks work this way is simple: they can't provide any DI because that inherently ties them to a DI framework. The only thing they can do (and should do) is provide classes that can be DI'd easily. If you are going for ultimate flexibility, the above code would also have public properties that can be assigned. That way, any DI-framework can be plugged in and use the framework with either constructor-based or property-based injection.

If you want to provide an amount of DI out-of-the-box for your objects, you'll need to create separate components that do the binding for your framework. For example, if I were using Castle Windsor for DI I would provide an Installer-class that can be plugged in.

Licencié sous: CC-BY-SA avec attribution
scroll top