0

Giving the following sample:

class Customer
{ 
    ICustomerRepository repository;

    private string name;

    public Customer(string name, ICustomerRepository repository)
    {        
        Name = name;
        this.repository= repository;
    }

    public string Name 
    { 
         get {return name;} 
         set 
         {
             if(String.IsNullOrWhiteSpace(value))
                 throw new ArgumentException();

             name = value;
        } 
    }
}
  • I'm using ninject IoC.
  • I abstract ninject container in an IFactory interface that has Get<>() method, so i want use only constructor injection. I do that because i don't want use [Inject] attributes.
  • I want follow the always valid entity principle.

In this scenario i can't do that because i have a parameter on constructor. There is an another approach to do that?

Edit:

  • I abstract ninject container in an IFactory interface that has Get<>() method, so i want use only constructor injection. I do that because i don't want use [Inject] attributes.

Abstraction of my the container:

interface IFactory
{
    T Get<T>();
    IEnumerable<T> GetAll<T>();
}

Implementation:

class ApplicationFactory : IFactory
{
    private readonly IKernel ninjectKernel = ApplicationNinjectKernel.BuildNew();

    public T Get<T>()
    {
        return ninjectKernel.Get<T>();
    }

    public IEnumerable<T> GetAll<T>()
    {
        return ninjectKernel.GetAll<T>();
    }
}

ApplicationNinjectKernel.BuildNew() creates and return a new StandarKernel() with the binds..

ConstructorArgument sounds bad to me. With this approach i will put some ugly thing on my code and also will miss type checking at project time. :/

Vinicius Gonçalves
  • 2,514
  • 1
  • 29
  • 54
  • 1
    Why are you trying to follow the "Always Valid Entity" principle. Are you aware that it is an anti-pattern? http://jeffreypalermo.com/blog/the-fallacy-of-the-always-valid-entity/ – Silas Reinagel Feb 20 '15 at 17:50
  • Look: https://andyhitchman.wordpress.com/2009/05/15/the-always-valid-entity-is-not-a-fallacy/ – Vinicius Gonçalves Feb 20 '15 at 17:51
  • 1
    I must be missing something. What exactly is the problem? – Sam Holder Feb 20 '15 at 18:04
  • 1
    @SamHolder, The OP can tell Ninject what to use when it sees `ICustomerRepository` as a parameter, but that's insufficient for creating an instance of this class. Ninject does have the ability to bind to a specific parameter name, but that's questionable. Using Ninject with a factory for this type is one possibility. – chris Feb 20 '15 at 18:07
  • 3
    Your `ApplicationFactory` closely resembles a service locator. You should be aware that many people consider this an antipattern. Instead, Ninject would only be used at the composition root (e.g., `Main`) and nowhere else would know which IoC container is being used, if any. – chris Feb 20 '15 at 18:42
  • Right! I Agree with you! The problem is that i'am using a Windows Forms application and i can't see how use IoC container just in composition root in this type of application. – Vinicius Gonçalves Feb 20 '15 at 19:19
  • Have you considered adding a T GetByName(string name) to your interface and factory? – Silas Reinagel Feb 20 '15 at 19:44
  • Hi @SilasReinagel, it make no sense for me. The code above is just a sample. I've thousands of anothers entities;. If i do T GetByName(string name), i will have thousands of interface methods (e.g. For each entity T GetByXxxx...)... – Vinicius Gonçalves Feb 20 '15 at 19:54
  • @ViniciusGonçalves In that case, it seems that this is not the right place to utilize a DI container. You should use Repository Pattern and simple POCO objects. There is no clean way to use DI to resolve repository entities selected by criteria (such as name). Your ICustomerRepository should return a Customer, instead of a Customer containing a reference to an ICustomerRepository. – Silas Reinagel Feb 20 '15 at 19:59
  • Related: https://stackoverflow.com/questions/4835046/why-not-use-an-ioc-container-to-resolve-dependencies-for-entities-business-objec – Steven Feb 23 '15 at 10:58

1 Answers1

1

If you are trying to use Ninject to resolve using a given customer name, you can do it like this:

var customer = kernel.Get<Customer>(new ConstructorArgument("name", "Bob"));

This also requires that you followed the convention of binding your ICustomerRepository in the Ninject Module and loaded it into the Ninject Kernel. Example:

public override void Load()
{
    Bind<ICustomerRepository>().To<CustomerRepository>();
}
Silas Reinagel
  • 4,155
  • 1
  • 21
  • 28
  • 1
    Unless you know the name up front (kind of unlikely), this is only possible when using Ninject as a service locator. – chris Feb 20 '15 at 18:22
  • 1
    @chris: That is correct. Although in this case the OP seems to be building a weird Factory alternative, in which he uses DI to create his entities. I'm not entirely certain what the goal of this is, but this is how it would be performed, given the code sample provided. – Silas Reinagel Feb 20 '15 at 18:24
  • Tks for reply. I edited my question, please, see again. – Vinicius Gonçalves Feb 20 '15 at 18:38