Constructor argument with struct type

3 views
Skip to first unread message

paul

unread,
Jul 19, 2008, 3:14:35 AM7/19/08
to structuremap-users

StructureMapConfiguration
.ForRequestedType<IFoo>()
.TheDefaultIs(
new ConfiguredInstance()
Instance<Foo>()
//.WithProperty("uniqueId").EqualTo(Guid.NewGuid())
.Child<Guid>("uniqueId").Is(Guid.NewGuid())
);


public class Foo : IFoo
{
private Guid _uniqueId;
public Foo(Guid uniqueId) { _uniqueId = uniqueId;}
}

Since Foo's constructor argument (Guid uniqueId) is a struct type,
neither the "Child" fluent call nor "WithProperty" fluent call works
for me.

Without documentation I am guessing that "Child" fluent call expects
an object type and "WithProperty" fluent call expects a literal type.
It appears to me that the struct type is left out in the cold?

Chad Myers

unread,
Jul 19, 2008, 3:56:43 AM7/19/08
to structure...@googlegroups.com
Paul,

The "WithProperty" is actually for properties, not C'tor arguments.

If you just need a new guid, you could do something like this:

StructureMapConfiguration
.ForRequestedType<IFoo>()
.TheDefaultIs(() => new Foo(Guid.NewGuid()));

That'll return a new Foo every time with a unique Guid.

If your problem is more complex than your example and this fix won't work,
let us know and we'll try something else.

-c

paul

unread,
Jul 19, 2008, 4:38:45 AM7/19/08
to structuremap-users
Chad,

Thanks for the example; what I want to do next is instantiate an
object as shown below.

Guid anotherGuid = anotherObject.GuidProperty;
var fooBasedOnAnotherObject =
ObjectFactory.With<Guid>(anotherGuid ).GetInstance<IFoo>();

Unfortunately it is not possible to do the above when using the
example you supplied. The way I am doing it currently is to to wrap
the Guid type with an object

public class WrappedGuid
{
public Guid InnerGuid { get; private set;}
public WrappedGuid (Guid innerGuid) { InnerGuid = innerGuid;}
}

public class Foo : IFoo
{
public Guid UniqueId {get; private set;};
public Foo(WrappedGuid wrappedId) { UniqueId =
wrappedId.InnerGuid;}

}
StructureMapConfiguration
.ForRequestedType<IFoo>()
.TheDefaultIs(
new ConfiguredInstance()
Instance<Foo>()
.Child<WrappedGuid>("wrappedId").Is(new
WrappedGuid(Guid.NewGuid()))
);

To instantiate Foo based on a Guid value supplied from another object
I would do the following

WrappedGuid anotherGuid = new WrappedGuid(anotherObject.GuidProperty);
var fooBasedOnAnotherObject =
ObjectFactory.With<WrappedGuid>(anotherGuid ).GetInstance<IFoo>();

Assert.IsTrue(anotherGuid.InnerGuid.Equals(fooBasedOnAnotherObject.UniqueId));

You can see I am taking an involved and a long way around. I hope
there would be a more direct way when using struct types.

-p

Chad Myers

unread,
Jul 19, 2008, 1:38:16 PM7/19/08
to structure...@googlegroups.com
Paul,

When messing around with your example last night, I ran into a few problems
with Guid myself. I think there's a bug in StructureMap's Reflection.Emit
when Guid.NewGuid() is involved. When I get some time I'll take your test
case and add a few of my own and try to work out a solution (or work with
Jeremy to get a fix).

It would be nice if you could do this:

StructureMapConfiguration.ForRequestedType<Guid>().TheDefaultIs(()=>
Guid.NewGuid());

But right now that throws an exception with something about "Common Language
Runtime detected an invalid program." That usually indicates a problem with
bogus IL being generated in a Reflection.Emit scenario.

I'll let you know what I come up with.

Thanks for hanging in there on this one!

-Chad

Chad Myers

unread,
Jul 19, 2008, 7:53:12 PM7/19/08
to structure...@googlegroups.com
Paul,

I just committed rev 127 to StructureMap's trunk that addresses this issue.
Incidentally, this should also resolve some issues with other value types
since this was a value type vs. ref type problem and nothing specific to
System.Guid.

You should be able to do this now:

public class IFoo
{
Guid SomeGuid{ get; set; }
}

public class Foo : IFoo
{
public Foo(Guid someGuid)
{
SomeGuid = someGuid;
}

Public Guid SomeGuid{ get; set; }
}

...

StructureMapConfiguration.ForRequestedType<Guid>().TheDefaultIs(()=>
Guid.NewGuid());
StructureMapConfiguration.ForRequestedType<IFoo>().TheDefaultIsConcreteType<
Foo>();

...

IFoo foo1 = ObjectFactory.GetInstance<IFoo>();
IFoo foo2 = ObjectFactory.GetInstance<IFoo>();

Console.WriteLine(foo1.SomeGuid);
Console.WriteLine(foo2.SomeGuid);

// console output shows two different Guids

paul

unread,
Jul 20, 2008, 12:56:24 AM7/20/08
to structuremap-users

Chad,

I checked out rev 127 and run some of my own unit tests injecting
struct(value) type constructor arguments, and I can confirm that it is
now working.

Thank you very much!

-p
Reply all
Reply to author
Forward
0 new messages