7

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

Johnno Nolan
  • 29,228
  • 19
  • 111
  • 160
superlogical
  • 14,332
  • 9
  • 66
  • 76

2 Answers2

8

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
  • 30,834
  • 11
  • 63
  • 78
  • 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? – superlogical Jul 02 '09 at 11:22
  • 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 Jul 02 '09 at 11:57
  • 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>(() => new NHRepository<>()); }); So I also need to know how to do that :( – superlogical Jul 02 '09 at 12:55
  • 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 Jul 02 '09 at 13:35
  • Yeah bro, I'm using .net 3.5, the problem is that the NHRepository is a generic like NHRepository 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>(()=>new NHRepository()); - But I'm really not sure if that will work either – superlogical Jul 02 '09 at 20:47
  • 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 Jul 03 '09 at 06:52
1

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<>));
superlogical
  • 14,332
  • 9
  • 66
  • 76