C# Dependency Injection – How to Deal with Dependency in Separate Projects?

cdependenciesdependency-injectionservice-locator

I know there is all this talk about having only one composition root that set all your dependencies and that you should always prefer constructor injection to other types, but sometimes it just doesn't make any sense for me. Here is my pseudo code :

    public class FakeModel
    {
        private FakeDependency Dependency = ServiceLocator.Get<FakeDependency>();

        public string Name { get; private set; }

        public FakeModel(string name)
        {
            Name = name;
        }

        public void UpdateName(string name)
        {
            Dependency.RandomAction();
            Name = name;
        }
    }

Special considerations :

  • FakeModel and FakeDependency sit in a class library project that is reused my many other projects.
  • All the other projects using this class library doesn't know, and shouldn't even know, that FakeDependency exists.
  • There will always be only one (+test) implementation of FakeDependency.
  • The only reason to replace the FakeDependcy is to run tests that only test the class library.

Would you rewrite this code differently, or it makes sense considering the requirements?

EDIT

There seems to be some confusion about the dependency, the service locator and how to use the class library. Think about the model as the public interface of this class library. Everything else is hidden from other projects, is undocumented and subject to changes anytime. You should not ever used any other methods than those define by the model.

About the service locator; it lives inside the class library project. It's only purpose is to make it possible to test the class library and absolutely not to inject new dependencies into this library. If I wanted to make it possible to replace the dependency I would of course have used constructor injection like that public FakeModel(string name, FakeDependency dependency) but that is not the case.

Then how do you use this class library currently? Just like that :

public void Test()
{
    var model = new FakeModel("MyName");
    model.UpdateName("NewName");
}

The class library should be self contained. Maybe using the word "dependency" is confusing as it's not something that you need to provide to the class library.

Best Answer

Yes I would rewrite it.

Edit: new code based on your expanded comments and question:

[assembly: InternalsVisibleTo("TestAssembly")]
    public class FakeModel
    {
        private IFakeDependency dependency;
        public string Name { get; private set; }

        public FakeModel(string name)
        {
            Name = name;
            this.dependency = new FakeDependency();
        }
        //use this constructor in tests
        internal FakeModel(string name, IFakeDependency dependency)
        {
            Name = name;
            this.dependency = dependency;
        }
        public void UpdateName(string name)
        {
            dependency.RandomAction();
            Name = name;
        }
    }