2

I've an API DLL (API.dll, for example) which, in addition to many other thinks, makes available an abstract class (AbstractClass).

Now making use of that AbstractClass I've implemented it on two different dlls:

  • First.API.Implementation.dll with ConcreteImplementation1
  • Second.API.Implementation.dll with ConcreteImplementation2

Both ConcreteImplementation1 and ConcreteImplementation2 are implementation of the same abstract class.

What I want is an application where I can choose which of those two dlls to use and, through that, choose which implementation to use without the user having to change anything within the code and, if possible, without stopping the application.

Some configuration file where I can bring the application to use whatever implementation I want. Something like:

<appconfiguration>
    <implementation_to_use>
        <dll>First.API.Implementation.dll</dll>
        <class>ConcreteImplementation1</class>
    </implementation_to_use>
</appconfiguration>

I know near to nothing about dependency injection, apart from its concept, but I guess thats the perfect fit for this task.

I've researched several DI/IoC libraries but I'm not familiar with all the concepts and names. I can use whatever library I want. For what I can say these are the most used: StructureMap, Ninject and Sprint.NET

Moreover, apart from all the dlls and implementation I need to indicate a file to be used by that application. Can I indicate its path in that same file?

I just need some tips and directions to implement such a thing. Some examples using one of those libraries, would be awesome.

Thanks.

Joao
  • 7,366
  • 4
  • 32
  • 48
  • 1
    You cannot have two distinct abstract base classes, both concrete implementations must derive from the same abstract class. Or interface, the more common choice. Then just use Activator.CreateInstance(). – Hans Passant Jun 15 '11 at 23:27
  • Sorry. The names used in the example were not well chosen. Both AbstractImplementation1 and AbstractImplementation2 ARE concrete implementations of the same abstract class. I'll edit the names. – Joao Jun 15 '11 at 23:40
  • You still need to fix the code snippet. It has to contain the name of the concrete type, not the abstract one. – Hans Passant Jun 16 '11 at 00:11
  • [MEF](http://mef.codeplex.com/) might be worth a look. – TrueWill Jun 18 '11 at 17:41

1 Answers1

2

To get you started using StructureMap, create a console application, include in it:

structuremap.config:

<?xml version="1.0" encoding="utf-8" ?>
<StructureMap MementoStyle="Attribute">
  <DefaultInstance
    PluginType="DemoIoC.AbstractBase,DemoIoC"
    PluggedType="DemoIoC.ConcreteImplementation1,DemoIoC"
    Scope="Singleton" />
</StructureMap>

The PluginType and PluggedType attributes are "FullyQualifiedClassName,AssemblyName" By default it will look for assemblies in the executable folder, I'm not sure how you would specify another location for the assemblies

There are plenty of options for Scope, e.g. Singleton, Transient, etc

Program.cs:

namespace DemoIoC
{
    using System;
    using StructureMap;

    public static class Program
    {
        public static void Main(string[] args)
        {
            // here you initialize structuremap from the config file.
            // You could probably use a FileSystemWatcher to reinitialize 
            // whenever the structuremap.config file changes
            ObjectFactory.Initialize(x =>
            {
                x.UseDefaultStructureMapConfigFile = true;
            });

            var concrete = ObjectFactory.GetInstance<AbstractBase>();

            concrete.Method1();

            Console.ReadKey(true);
        }
    }
}

AbstractBase.cs:

namespace DemoIoC
{
    public abstract class AbstractBase
    {
        public abstract void Method1();
    }
}

ConcreteImplementation1.cs:

namespace DemoIoC
{
    using System;

    public class ConcreteImplementation1 : AbstractBase
    {
        public override void Method1()
        {
            Console.WriteLine("Called ConcreteImplementation1");
        }
    }
}
Patrick McDonald
  • 64,141
  • 14
  • 108
  • 120
  • Perfect! That's just the push that I needed. – Joao Jun 16 '11 at 01:23
  • just one more quick question. Abstract class receives an StreamReader as ctor parameter. How can I indicate it, through XML configuration file? Something like – Joao Jun 16 '11 at 02:18
  • Have a look at http://stackoverflow.com/questions/2824088/passing-constructor-arguments-when-using-structuremap, this shows how to create an object with a parameter known only at runtime, its not clear however how to specify this in the XML configuration – Patrick McDonald Jun 16 '11 at 10:34