Register a default instance in StructureMap

2019-04-15 04:24发布

问题:

I have a class (MyService) that has a static property (MyService.Context) which represents a current context (which is specific to currently logged in user, so it changes).

What i'm trying to achieve i

ObjectFactory.Initialize(x =>
            {
                x.For<IMyService>().Use<MyInstance>(c => c.Use(MyService.Context));
            });

I.e. so that for every ObjectFactory.GetInstance<IMyService>() i get a reference to MyService.Context

Is that doable?

UPDATE

I can't use a singleton pattern since MyService.Context changes depending on the user making a request (via HttpContext).

In the pseudo-code above lambda parameter c represents a SM context, so that i can return a custom result for each request. I'm aware of SM's Intercept() but it's fired after the object is constructed - not instead.

回答1:

If you can work with a property there is the possibility to add a OnCreation method. The Action provided is executed against the instance just after creation:

ObjectFactory.Initialize(x =>
        {
            x.For<IMyService>()
             .Use<MyInstance>()
             .OnCreation(x => x.Context = MyService.Context;
        });

Or you can use lazy initialization and provide a Func to the Use method which is executed whenever a new instance is needed. This should execute in the right context:

ObjectFactory.Initialize(x =>
        {
            x.For<IMyService>()
             .Use<MyInstance>(() => new MyInstance(MyService.Context);
        });

I hope one of this methods works for you.



回答2:

Provided that the MyService has a ctor argument for the IContext:

For<IContext>().Add(c => MyService.Context).Named("context");
For<IMyService>().Use<MyService>()
    .Ctor<IContext>().Is(c => c.GetInstance<IContext>("context"));

or if you want to default the context for all dependees:

For<IContext>().Use(() => MyService.Context);
For<IMyService>().Use<MyService>();

The lambda expression will in both cases cause the context to be resolved upon requesting the MyService instance.