tags:

views:

253

answers:

2

I am trying to configure the NCommon NHRepository in my project with Structure Map. How do I stop it from choosing the greediest constructor?

 public class NHRepository<TEntity> : RepositoryBase<TEntity>
 {

    public NHRepository () {}


    public NHRepository(ISession session)
    {
        _privateSession = session; 
    }

    ...
}

My structure map configuration

ForRequestedType(typeof (IRepository<>))
                .TheDefaultIsConcreteType(typeof(NHRepository<>))

Cheers Jake

+2  A: 

You can set the [DefaultConstructor] Attribute for the constructor you wish as a default. In your case, setting it on the NHRepository() constructor would make it the default constuctor for StructureMap to initialize.

Update: well, in the latest version of StructureMap, using .NET 3.5 you can also specify it using the SelectConstructor method:

var container = new Container(x =>
{
  x.SelectConstructor<NHRepository>(()=>new NHRepository());
});

Finally, I'm sure you would be able to define it in the XML configuration of StructureMap, but I haven't used that. You could do a little search on it. For more information on the above method, see: http://structuremap.sourceforge.net/ConstructorAndSetterInjection.htm#section3

Razzie
Hi Razzie, cheers for the answer, however the NHRepository is in the NCommon.NHibernate.dll which I cannot change. So should I just inherit from the NHRepository in my project, and put the attribute on its constructor instead?
Jake Scott
I hadn't though about that. See my updated answer to use the SelectConstructor method, but that's only possible in .NET 3.5
Razzie
Wicked thanks so much for this! Stackoverflow is awesome!
Jake Scott
Also I am still not sure how to use that syntax as I the compiler will not allow var container = new Container(x => { x.SelectConstructor<NHRepository<>>(() => new NHRepository<>()); });So I also need to know how to do that :(
Jake Scott
You will need .NET 3.5 for that, as stated in my post. Are you perhaps running 2.0? If so, it is time for an upgrade :-)
Razzie
Yeah bro, I'm using .net 3.5, the problem is that the NHRepository is a generic like NHRepository<Region> etc. So the above syntax doesn't compile. If you look at my orignal configuration you will notice I have to use the typeof (IRepository<>) syntax. So I don't think structor map supports that in the fluent configuration. Unless I force all my entities to implement IEntity, the I could use x.SelectConstructor<NHRepository<IEntity>>(()=>new NHRepository<IEntity>()); - But I'm really not sure if that will work either
Jake Scott
Ah, I'm sorry Jake, I totally didn't notice the generic brackets in your comment. I thought it complained about lambda syntax, go figure :( Anyway, I'm not really sure how you would do this with StructureMap, sorry. Your best best is to ask it on the StructureMap discussion board then: http://groups.google.com/group/structuremap-users/topics?hl=en. Good luck!
Razzie
A: 

So +1 for Razzie because this would work if the NHRepository was in my own assembly, instead I choose to wrap the NHRepository with my own Repository like below..

public class Repository<T> : NHRepository<T>
{
    [DefaultConstructor]
    public Repository()
    {

    }

    public Repository(ISession session)
    {

    }
}

ForRequestedType(typeof (IRepository<>))
                .TheDefaultIsConcreteType(typeof (Repository<>));
Jake Scott