views:

318

answers:

4

I'm a bit of a DI newbie, so forgive me if this is the wrong approach or a silly question.

Let's say I have a form which creates/updates an order, and I know it's going to need to retrieve a list of products and customers to display. I want to pass in the Order object that it's editing, but I also want to inject the ProductsService and CustomersService as dependencies.

So I will want my IoC container (whichever one I go with) to supply the services, but it'll be up to the calling code to supply the Order object to edit.

Should I declare the constructor as taking the Order object as the first parameter and the ProductsService and CustomersService after that, eg:

public OrderForm(Order order, ProductsService prodsSvc, CustomersService custsSvc)

... or should the dependencies come first and the Order object last, eg:

public OrderForm(ProductsService prodsSvc, CustomersService custsSvc, Order order)

Does it matter? Does it depend on which IoC container I use? Or is there a "better" way?

+3  A: 

Matt, you shouldn't mix normal parameters with dependencies. Since your object will be created in the internals of IoC container, how are you going to specify necessary arguments?

Mixing dependency and normal arguments will make logic of your program more complicated.

In this case it would be better to declare dependency properties (i.e. remove dependencies from constructor) or initialize order field after IoC constructed OrderForm and resolved it's dependencies (i.e. remove normal parameters from constructor).

Also you can declare all of your parameters, including order as dependencies.

aku
Ok, this is making sense. So either I use property injection for all my dependencies, or ONLY pass dependencies into the ctor and introduce a property for the "necessary" object?
Matt Hamilton
Yes, you're right. Don't mix DP and normal properties because it can lead to unpredicted problems and limit the range of suitable IoC frameworks.
aku
+3  A: 

I feel a bit uneasy about allowing an instance of OrderForm to be instantiated without the required reference to an Order instance. One reason might be that this would prevent me from doing upfront checking for null orders. Any further thoughts?

I suppose I could take some comfort in knowing that OrderForm objects will only be instantiated by a Factory method that ensures the Order property is set after making the call to the IoC framework.

Mario
A: 

@Mario,

In my answer I proposed several approaches including one with mandatory order parameter.

Questions however was about mixing DP and normal properties. My answer is - don't mix.

I would be happy to hear constructive criticism.

aku
Shouldn't this be a comment on Mario's answer?
Jacob Stanley
+3  A: 

I disagree with @aku's answer.

I think what you're doing is fine and there are also other ways to do it that are no more or less right. For instance, one may question whether this object should be depending on services in the first place.

Regardless of DI, I feel it is helpful to clarify in your mind at least the kind of state each object holds, such as the real state (Order), derived state (if any), and dependencies (services):

http://tech.puredanger.com/2007/09/18/spelunking/

On any constructor or method, I prefer the real data to be passed first and dependencies or external stuff to be passed last. So in your example I'd prefer the first.

Alex Miller