Re: Getting started with structuremap

142 views
Skip to first unread message

Jeremy Miller

unread,
Mar 16, 2013, 5:37:06 PM3/16/13
to structure...@googlegroups.com
How are you consuming DefaultBus?  Are you injecting IBus, or injecting the concrete class?  The HttpContextScoped() business is only going to apply to requests for IBus.

On Saturday, March 16, 2013 4:30:26 PM UTC-5, Luis Abreu wrote:
Hello guys.

I've started using structuremap and I've got a problem regarding the use of the HttpContextScoped lifecycle. I've got the following:

amespace Dri.employees.Web.Configuration {
    public class EmployeeRegistry : Registry {
        public EmployeeRegistry() {
            For<IBus>()
                .HttpContextScoped()
                .Use<DefaultBus>();

            For<IRouter>()
                .Singleton()
                .Use( () => new DefaultRouter());

            For<IDepartmentValidationService>()
                .Use<DepartmentValidationService>();
            
            var eventsCnnString = ConfigurationManager.ConnectionStrings["events"].ConnectionString;
            For<IEventStore>()
                .HttpContextScoped()
                .Use(() => new EventStore(eventsCnnString,
                                          ObjectFactory.GetInstance<IFormatter>(),
                                          ObjectFactory.GetInstance<IBus>()));

            For(typeof (IDomainRepository<>))
                .Use(typeof (DefaultDomainRepository<>));
            

            For<IDomainRepository<Department>>()
                .Use<DefaultDomainRepository<Department>>();

            var reportCnnString = ConfigurationManager.ConnectionStrings["reports"].ConnectionString;
            For<ISession>()
                .HttpContextScoped()
                .Use(() => new NhFluentConfigurationBuilder(reportCnnString).GetSession());
        }
    }

}

DefaultBus is used by several components. My problem is that DefaultBus ends up being instantiated several times during the same request. How is this possible? I mean, looking at my config, it seems like it's correct (I've checked this by adding a private guid field which has different values when used from several components). Am I Wrong? How can I debug this kind of problems?

thanks

Luis Abreu

unread,
Mar 17, 2013, 6:13:48 AM3/17/13
to structure...@googlegroups.com
Hello Jeremy.


On Saturday, March 16, 2013 9:37:06 PM UTC, Jeremy Miller wrote:
How are you consuming DefaultBus?  Are you injecting IBus, or injecting the concrete class?  The HttpContextScoped() business is only going to apply to requests for IBus.


All my dependencies are injected through interfaces passed into the constructors. Here are some examples:

public DepartmentCreatedHandler(ISession session, IDepartmentValidationService service, IBus bus) {
            Contract.Requires(session != null);
            Contract.Requires(service != null);
            Contract.Requires(bus != null);
            Contract.Ensures(_service != null);
            Contract.Ensures(_bus != null);
            Contract.Ensures(_session != null);
            _session = session;
            _service = service;
            _bus = bus;
 }

public DepartmentController(IBus bus, ISession session) {
            Contract.Requires(bus != null);
            Contract.Requires(session != null);
            Contract.Ensures(_bus != null);
            Contract.Ensures(_session != null);
            _bus = bus;
            _session = session;
}

this web app has several web api services (the last example shows an example of one of those services) which are constructed through an http activator:

 public class WebApiActivator : IHttpControllerActivator {
        public IHttpController Create(HttpRequestMessage request,
                                      HttpControllerDescriptor controllerDescriptor,
                                      Type controllerType) {
            IHttpController controller = null;
            try {
                controller = (IHttpController) ObjectFactory.GetInstance(controllerType);
            }
            catch {
            }
            return controller ??
                   new DefaultHttpControllerActivator().Create(request, controllerDescriptor, controllerType);
        }
    }

There are a couple of places where I'm explicitly calling the ObjectFactory method (after adding my registry class,  I'm personalizing the IRouter singletone instance with some code that registers the handles for my commands and  events), but I'm assuming that getting an instance of an object through ObjectFactory ends up respecting the definitions I've set up on my registry object, right?

btw, any tips on how to debug what's going on?

thanks again.

Luis Abreu

unread,
Mar 17, 2013, 2:44:26 PM3/17/13
to structure...@googlegroups.com
One more thing: when relying in  the concrete type instantiation without registering the type, does structuremap respects the life cycle defined during registration? For isntance, I've got something like this:

ObjectFactory.Initialize(..);
RegisterHandlers();

and RegisterHandlers has code which looks like this:

var handler = ObjectFactory.GetInstance(cmdHandlerType); //cmdHandler was not registered explictely

if cmdHandlerType's constructor expects a reference to an IBus, will the current http context's bus be reused? I?m asking this because one of the handlers expects a reference to an IBus and it's getting a different instance from the one that is being passed to the other components that have been registered.

thanks again.

Luis Abreu

unread,
Mar 18, 2013, 4:59:04 PM3/18/13
to structure...@googlegroups.com
Hello again.

After some debugging, I've finally spotted the problem. It was buried deep down in the reflection code used for registering the handlers used by the bus. instead of creating an action which would then be responsible for creating the handler, it was creating a single handler which would be reused in all the requests (and that's why I ended up having 2 bus instances in the same request).

Bottom line: as I thought, the problem was mine and not in structuremap's code.

sorry for wasting your time guys!

Luis 
Reply all
Reply to author
Forward
0 new messages