views:

706

answers:

2

Hi, is it possible to get this stuff working(some way to force Objectfactory create instances like Activator)

in the below example everything is placed in a sigle assembly

public interface IUnitOfWorkFactory
{
    IUnitOfWork Create();
}

internal class NHUnitOfWorkFactory : IUnitOfWorkFactory
{
    public IUnitOfWork Create()
    {
        ////  do needed stuff
    }
}

bootstrapping :

ObjectFactory.Configure(x =>
{
    x.ForRequesedType<IUnitOfWorkFactory>.TheDefaultIsConcreteType<NHUnitOfWorkFactory>();
});

usage:

IUnitOfWorkFactory factory = ObjectFactory.GetInstance<IUnitOfWorkFactory>();

My result:

Porktal.Core.Tests.UnitOfWorkTests.Can_Start_Unit_of_Work : StructureMap.StructureMapException : StructureMap Exception Code:  207
Internal exception while creating Instance 'Porktal.Core.Data.NH.NHUnitOfWorkFactory, Porktal.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' of PluginType Porktal.Core.Data.IUnitOfWorkFactory.  Check the inner exception for more details.
---- System.MethodAccessException : Porktal.Core.Data.NH.NHUnitOfWorkFactory..ctor()
Stack Trace:
   at StructureMap.Pipeline.ConfiguredInstanceBase`1.StructureMap.Pipeline.IConfiguredInstance.Build(Type pluginType, BuildSession session, InstanceBuilder builder)
   at StructureMap.Pipeline.ConfiguredInstanceBase`1.build(Type pluginType, BuildSession session)
   at StructureMap.Pipeline.Instance.createRawObject(Type pluginType, BuildSession session)
   at StructureMap.Pipeline.Instance.Build(Type pluginType, BuildSession session)
   at StructureMap.Pipeline.BuildPolicy.Build(BuildSession buildSession, Type pluginType, Instance instance)
   at StructureMap.InstanceFactory.Build(BuildSession session, Instance instance)
   at StructureMap.BuildSession.CreateInstance(Type pluginType, Instance instance)
   at StructureMap.BuildSession.b__0(Type t)
   at StructureMap.Util.Cache`2.get_Item(KEY key)
   at StructureMap.BuildSession.CreateInstance(Type pluginType)
   at StructureMap.Container.GetInstance(Type pluginType)
   at StructureMap.Container.GetInstance[T]()
   at StructureMap.ObjectFactory.GetInstance[PLUGINTYPE]()
   at Porktal.Core.Bootstraper.Bootstrap() in D:\Porktal\Porktal.Core\Bootstraper.cs:line 20
   at Porktal.Core.Tests.UnitOfWorkTests.Can_Start_Unit_of_Work() in D:\Porktal\Porktal.Core.Tests\UnitOfWorkTests.cs:line 11
----- Inner Stack Trace -----
   at PorktalCoreDataNHNHUnitOfWorkFactoryInstanceBuilder44203c8113d44053be045df4db28c3dc.BuildInstance(IConfiguredInstance , BuildSession )
   at StructureMap.Pipeline.ConfiguredInstanceBase`1.StructureMap.Pipeline.IConfiguredInstance.Build(Type pluginType, BuildSession session, InstanceBuilder builder)

+2  A: 

You have 2 options. You can make NHUnitOfWorkFactory public (preferred).

Or you can put the code that constructs your internal class in your assembly (where it has access to internal members) in the form of a lambda , and pass it to StructureMap:

ObjectFactory.Configure(x => {
  x.ForRequestedType<IUnitOfWorkFactory>()
   .TheDefault.Is.ConstructedBy(() => new NHUnitOfWorkFactory())
});

The equivalent with newer versions of StructureMap is:

ObjectFactory.Configure(x => {
  x.For<IUnitOfWorkFactory>().Use(() => new NHUnitOfWorkFactory())
});
Joshua Flanagan
My I add a +1 to the make it public sentiment.
KevM
In more recent versions of StructureMap, the preferred usage is: x.For<IUnitOfWorkFactory>().Use(new NHUnitOfWorkFactory());
Richard J Foster
Richard - that is incorrect (but a common mistake). Your example would create a singleton NHUnitOfWorkFactory instantiated at registration time. My example showed creating a new instance of the factory for each request, at request time. I've updated my answer with the correct new syntax.
Joshua Flanagan
A: 

I haven't verified this, but making the internals of the assembly of NHUnitOfWorkFactory visible to the StructureMap assembly might do the trick.

You use the InternalsVisibleTo attribute in your AssemblyInfo class.

Martin R-L
Tried it, it doesn't work.
Pawel Lesnikowski