سؤال

While re-factoring a project with the objective of not making it dependent on a concrete type but an abstraction of it I've been faced to the issue that I would need to add a reference to a project which I didn't want to.

So I've sketched the following piece of code which works pretty well :

Usage :

// Old line of code that directly referenced AudioStream
// AudioStream = new AudioStream(value);

// New code that tries to find a concrete implementation of IAudioStream
var type = typeof(IAudioStream);
var implementation = TryFindImplementation<IAudioStream>();
if (implementation == null)
    throw new InvalidOperationException(
        "Could not find an implementation of " + type.Name);
var instance = Activator.CreateInstance(implementation, value);
AudioStream = (IAudioStream)instance;

Method that tries to find a concrete implementation:

private static Type TryFindImplementation<T>()
{
    return (    
        from assembly in AppDomain.CurrentDomain.GetAssemblies()
        from type in assembly.GetTypes()
        where typeof(T).IsAssignableFrom(type)
        where type != typeof(T)
        select type)
        .FirstOrDefault();
}

Can this piece of code considered as a very simple form of Dependency Injection ?

هل كانت مفيدة؟

المحلول

No, that's not Dependency Injection.

Instead, consider injecting either the IAudioStream dependency, or a factory thereof, into your client code.

public class AudioStreamClient
{
    private readonly IAudioStream audioStream;

    public AudiStreamClient(IAudioStream audioStream)
    {
        this.audioStream = audioStream;
    }

    public void DoStuff()
    {
        // use this.audioStream here...
    }
}

Alternatively, if you need a new instance of IAudioStream every time DoStuff executes, consider injecting an Abstract Factory instead.

However, be mindful that this might be a Leaky Abstraction, and a better alternative is to create an Adapter that manages the object's lifetime for you.

نصائح أخرى

No. This is not simple, it's quite advanced. The simple way would be passing AudioStream into the method as a parameter.

Your code can be considered as a simple dependency injection framework - and in my opinion there are enough of them and you don't need to write your own.

It looks like a limited Service Locator implementation. Activator.CreateInstance will throw an exception if there is no default constructor for the type you are trying to instantiate. Any decent container can handle this functionality and you could use constructor injection for all of your types.

If you can't or don't want to use an DI container, make sure that it's tested well.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top