Please Help - DI with a List<Generic>

4 views
Skip to first unread message

Bill

unread,
Oct 6, 2008, 8:17:57 PM10/6/08
to Test Driven Development
Hi,

Using DI for an object seems to work as I would expect but today I ran
into a situation where I am newing up an object in a loop and adding
it to a List<Shipment> type in side my class. I can't seem to figure
out how to handle this situation so I can decouple the dependence of
the object that I need to create in the loop and populate with data
before adding it to the generic List<Ship>. Any ideas, or am I totally
off base with trying to do this and should be doing something
completely different?

public class ProcessShipmentObject
{
private readonly ShipmentManagerObj manager;
public ProcessShipmentObject(): this(new ShipmentManagerObj(), new
ShipmentObj())
{
//nothing
}

public ProcessShipmentObject(ShipmentManagerObj manager,
ShipmentObj shipment)
{
this.manager = manager;
}

public ShipmentManagerObj returnShipmentCollection()
{
try
{
// This object was easy to inject
//ShipmentManagerObj shipmentManagerObj = new
ShipmentManagerObj();
ReadVRAFile readFile = new ReadVRAFile();
List<string> vraTestList = new List<string>();
int count = readFile.ReadFromTestFile(vraTestList);
if (manager == null)
{
return null;
}
return manager;
}
catch (Exception e)
{
System.Console.WriteLine("returnShipmentCollection - " +
e.ToString());
return null;
}
}

public ShipmentManagerObj GetShipment(List<string>list)
{
try
{
int count = 0;
//ShipmentManagerObj shipmentManagerObj = new
ShipmentManagerObj();
foreach (string str in list)
{

// How can I inject this? Or is there a better way to do
this??
ShipmentObj shipment = new ShipmentObj();
string stopID = str.Substring(0, 12).Trim();
.
.
.
ShipmentTimeWindowObj shipTW = new
ShipmentTimeWindowObj();
shipTW.ShipmentID = shipment.ShipmentID;
.
.
.
shipTW.ServiceCode = "000";
shipment.AddTimeWindow(shipTW);

count++;

manager.AddShipment(shipment);
}

Thanks in advance!!
Bill

Nick Parker

unread,
Oct 6, 2008, 8:36:21 PM10/6/08
to Test-Driven...@googlegroups.com
Bill,

Are you just looking for a way to handle the construction of your ShipmentObj within the for loop?  If so, you might look at extracting the construction knowledge of the ShipmentObj into a Builder class that knows the mechanics of assembling a ShipmentObj.  HTH

Javier G. Lozano

unread,
Oct 6, 2008, 8:52:20 PM10/6/08
to Test Driven Development
Hi Bill,

I agree with Nick here. Typically, you can have an builder that you
inject to the constructor for your desired type.

So,

public ShipmentObj(IShipmentBuilder builder)
{
// Builder code goes here
}



On Oct 6, 7:36 pm, "Nick Parker" <ni...@developernotes.com> wrote:
> Bill,
> Are you just looking for a way to handle the construction of your ShipmentObj
> within the for loop?  If so, you might look at extracting the construction
> knowledge of the ShipmentObj into a Builder class that knows the mechanics
> of assembling a ShipmentObj.  HTH
>
> Nick Parkerwww.developernotes.com
>

Nick Parker

unread,
Oct 6, 2008, 8:56:13 PM10/6/08
to Test-Driven...@googlegroups.com
Javier,

I believe he is trying to build the ShipmentObj, so he wouldn't want to place the builder within the ctor of the ShipmentObj itself.

Javier G. Lozano

unread,
Oct 6, 2008, 9:04:32 PM10/6/08
to Test Driven Development
He can inject the builder into the constructor of ShipmentObj (through
a DI container or poor-man's) so the actual "build" logic is still
encapsulated in the builder implementation.

On Oct 6, 7:56 pm, "Nick Parker" <ni...@developernotes.com> wrote:
> Javier,
> I believe he is trying to build the ShipmentObj, so he wouldn't want to
> place the builder within the ctor of the ShipmentObj itself.
>
> Nick Parkerwww.developernotes.com

Bill

unread,
Oct 6, 2008, 9:24:09 PM10/6/08
to Test Driven Development
Hi Nick,

Thanks for getting back to me so quick. I was thinking that since
inside the loop I must new up ShipmentObj's to add them to the List
that this tightly couples my class to the ShipmentObj. Since I need a
ShipmentObj each time through the loop, I can't really see how else I
might do that. If I use a Builder, would that remove the dependency of
having this tight coupling? Or would this be similar to a factory to
construct the ShipmentObj? I'll have to look at my books tomorrow in
the office and see exactly how to create the Builder. Maybe that will
make it all more clear to me.

thanks!!
Bill
> > Bill- Hide quoted text -
>
> - Show quoted text -

Nick Parker

unread,
Oct 6, 2008, 9:28:41 PM10/6/08
to Test-Driven...@googlegroups.com
Javier,

I'm not sure something like that would necessarily be needed if the domain model were adjusted.  Having Foo call a builder.Initialize(this); seems kinda funky in this case.

Javier G. Lozano

unread,
Oct 6, 2008, 9:31:35 PM10/6/08
to Test Driven Development
Totally agree with you. Bill is trying to target two things (state
initialization and object construction) with a single blow which is
made hard because of the way he currently has his domain model. From
this point, it's a bit of overkill to try to use DI for what he's
trying to do when a simple factory pattern will suffice.

On Oct 6, 8:28 pm, "Nick Parker" <ni...@developernotes.com> wrote:
> Javier,
> I'm not sure something like that would necessarily be needed if the domain
> model were adjusted.  Having Foo call a builder.Initialize(this); seems
> kinda funky in this case.
>
> Nick Parkerwww.developernotes.com

Nick Parker

unread,
Oct 6, 2008, 9:32:28 PM10/6/08
to Test-Driven...@googlegroups.com
Bill,

Involving the use of a builder isn't going to separate you from the ShipmentObj, but the construction of it.  This allows you to localize the parameters needed for internal state creation, etc.

Bill

unread,
Oct 6, 2008, 9:37:44 PM10/6/08
to Test Driven Development
Hi Javier,

So, it would be better in this case if I used a factory to create and
initialize my ShipmentObj's? Would that break the dependency I have
with the "new ShipmentObj()"?

thanks!
Bill

Bill

unread,
Oct 6, 2008, 9:42:07 PM10/6/08
to Test Driven Development
Nick,

Oh, and I got to this place as I was trying to figure out how I might
write a test for this method - since it new's up the ShipmentObj.
Maybe I'm really missing something here but it seems like that alone
makes any test an integration test since it uses other objects.

thanks again!
Bill

On Oct 6, 9:32 pm, "Nick Parker" <ni...@developernotes.com> wrote:
> Bill,
> Involving the use of a builder isn't going to separate you from the
> ShipmentObj, but the construction of it.  This allows you to localize the
> parameters needed for internal state creation, etc.
>
> > > - Show quoted text -- Hide quoted text -

Nick Parker

unread,
Oct 6, 2008, 9:43:50 PM10/6/08
to Test-Driven...@googlegroups.com
Bill,

You can localize the construction of your ShipmentObj with a builder.  A builder allows you to focus on the construction of the various relationships within your object model, eventually allowing you to adjust and grow the model itself and minimize the spread of the construction knowledge across your source.

Nick Parker

unread,
Oct 6, 2008, 9:47:24 PM10/6/08
to Test-Driven...@googlegroups.com
Bill,

What are you trying to test?

Bill

unread,
Oct 6, 2008, 9:57:57 PM10/6/08
to Test Driven Development
Nick,

That original method "GetShipment(List<string>list)" which returns a
list of ShipmentObj's populated with their properties. I was thinking
that a list that contains a number of populated custom objects would
be a fairly common scenario. Is there a better domain model for
creating this?

thanks!
Bill

On Oct 6, 9:47 pm, "Nick Parker" <ni...@developernotes.com> wrote:
> Bill,
> What are you trying to test?
>

Nick Parker

unread,
Oct 6, 2008, 10:12:18 PM10/6/08
to Test-Driven...@googlegroups.com
Bill,

I don't know anything about your domain.  You have a method call GetShipment(IList<string> list) that returns a ShipmentObj, is that correct?  Is it querying for the shipment from a data store or are you simply constructing a ShipmentObj?

Javier G. Lozano

unread,
Oct 6, 2008, 10:50:38 PM10/6/08
to Test Driven Development
Yes, if you have a factory for the ShipmentObj, it will eliminate the
dependency on the constructor ... the only thing that will need to
know about the constructor is the factory of ShipmentObj.

Bill

unread,
Oct 7, 2008, 9:57:59 AM10/7/08
to Test Driven Development
Morning Nick,

GetShipment actually returns a ShipmentList which is a list of all of
the ShipmentObj(s) and all of their childern.

This is a logistics application where we have an input file which
contains all the "stops" information. These stop records are used to
populate our entity objects. The top entity is a collection of
ShipmentObj(ects). Each of these ShipmentObj contain collections (or
lists if you will) of other objects like TimeWindowsList, VehicleList,
and DepotList objects that can be a variable number of items. I was
reading through the Build pattern that you had mentioned and it looks
similar to what I am discussing here. I understand how I can inject
the ShipmentCollection object into the ShipmentManager so that the
manager is not coupled directly to the collection and I can then
inject a test object instead to test the ShipmentManager. Since the
ShipmentCollection will contain ShipmentObj(s) would that mean that I
would have to inject the Builder to create the ShipmentObj(s) so that
I can inject a list of test objects instead? I am trying to figure out
how to create a collection of ShipmentObjs without having a loop that
"news" up one and then adds it to the collection. That couples the
collection class to the ShipmentObj class, right? And that is one of
the things that we are trying to avoid, correct?
I feel like I am missing something, but not sure what. :) I'm sorry I
can't seem to be able to explain this more clearly.

thanks!
Bill

On Oct 6, 10:12 pm, "Nick Parker" <ni...@developernotes.com> wrote:
> Bill,
> I don't know anything about your domain.  You have a method call
> GetShipment(IList<string> list) that returns a ShipmentObj, is that correct?
>  Is it querying for the shipment from a data store or are you simply
> constructing a ShipmentObj?
>

Nick Parker

unread,
Oct 7, 2008, 11:13:22 AM10/7/08
to Test-Driven...@googlegroups.com
Bill,

So it sounds like you need a repository to query for your shipments, the data store is a file, I think you are calling this your ShipmentManager.  I don't think it matters that the ShipmentManager knows about your ShipmentObj's, it should.  What I am  suggesting is that it might not need to know how to construct the ShipmentObj itself, that is what can be localized to a builder.

Bill

unread,
Oct 7, 2008, 11:37:49 AM10/7/08
to Test Driven Development
Nick,

Yes - that makes sense.. and I think that the collection manager as we
call it is really a repository. I found that I can create the
ShipmentObj with a factory, but I don't need to be able to stick in a
test double for the factory.create? And is it typical that I can set
the propertys of the ShipmentObj in the create method - or is the
create method more like a constructor that shouldn't do those kinds of
things?

thanks!!
Bill

On Oct 7, 11:13 am, "Nick Parker" <ni...@developernotes.com> wrote:
> Bill,
Reply all
Reply to author
Forward
0 new messages