Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constructor Injection - where to call?

I'm a little bit confused around Constructor Injection pattern and rule Don’t call the container; it’ll call you.

Can somebody explain me (and maybe someone else) how real application should derive all DI advantage using Constructor Injection ? I give for that some simple and i think common example:

DomainObject
RepositoryObject
DaoObject

The relations is obvious (I think) - RepositoryObject need DaoObject,DomainObject need Repository.

Using Constructor Injection I assume that I can forget (in most cases) about NEW keyword, but when, where and how should I create new objects (mainly domain)? I must write factories for all classes? Should I refer to DI Container in that factory?

The best will be when somebody show me some real app example (please not Asp.Net MVC :) ) or sketch some project structure.

like image 248
mgibas Avatar asked Nov 04 '22 18:11

mgibas


2 Answers

I don't get your class relationship so here's a more obvious ;-) example:

class FooService
{
    IFooRepository FooRepository { get; set; }

    public Service(IFooRepository fooRepository)
    {
        this.FooRepository = fooRepository;
    }
}

class Controller
{
    IFooService FooService { get; set; }
    IBarService BarService { get; set; }

    public Controller(IFooService fooService, IBarService barService)
    {
        this.FooService = fooService;
        this.BarService = barService;
    }
}

As you've already said - there is no new FooRepository() nor new FooService() code anywhere.

like image 89
Jakub Konecki Avatar answered Nov 09 '22 07:11

Jakub Konecki


The answers and Mark Seemann's link is enough but i want to add something. As a beginner to DI ( which i am) this question is always bugs me: "Ok there is no new but when and how my real objects are called and injected?". It took me for a while for me to understand and apply.

As you follow the answers and links you will see that. You should register your interfaces and classes in your applications Global.asax file for web application. For instance if you are using Ninject go to nuget and download Ninject.Web ( which is for webforms) and apply it like in this example http://azolotar.blog.com/2010/06/22/ninject-2-0-in-webforms/

Keypoint in the example.

  • Global.asax is inherited from NinjectHttpApplication ( which is in Ninject.Web.dll)
  • CreateKernel method is overridden this is where you create the kernel and tell your dependecy map to container
  • BasePage : this is for webforms so your interface in pages would be resolved if they are all derived from basepage.

I should add this, BasePage implementation is pretty easy ( here is the code on github) you probably already have an basepage so adding this line KernelContainer.Inject(this); to your base page's OnInit can solve the problem. One last remainder, if you are going to use anything in ascx you should override your ascx's OnInit so container can solve dependencies.

I know you said no MVC or web :)But the logic is the same

  • Set your depenceny map on start of application ( Main? for windows)
  • Since its not web no url no directly calling forms you will call it How to use Ninject in a Windows Forms application? as in this example. Dont know if you are using some patters MVP or MVVM but this can be a starting point

Damn this sounds not helpful answer but anyway , hope this helps.

like image 35
adt Avatar answered Nov 09 '22 05:11

adt