Structuremap configuration: One object, multiple interfaces - structuremap

I have this object "mySessionObject" of type "SessionObject". It implements the interfaces IMessageHandler<MessageA> and IMessageHandler<MessageB>. I should only have one of these objects, and it should live thru the entire HttpSession.
How do I register it with structuremap so that I at any time in the lifetime of the HttpSession can get it by calling ObjectFactory.GetInstance<IMessageHandler<MessageA>>(), or ObjectFactory.GetInstance<IMessageHandler<MessageB>>() ?

Inside of your normal StructureMap configuration, I would add this code:
ObjectFactory.Initialize(x =>
{
x.ForRequestedType<IMessageHandler<MessageA>>().
TheDefaultIsConcreteType<MyImplementingClass>().
CacheBy(InstanceScope.HttpSession);
x.ForRequestedType<IMessageHandler<MessageB>>().
TheDefaultIsConcreteType<MyImplementingClass>>().
CacheBy(InstanceScope.HttpSession);});
}
Note that you will need the 2.5.3 StructureMap release as detailed in this SO thread: StructureMap CacheBy InstanceScope.HttpSession not working
I'm away from a compiler at the moment, but I believe that CacheBy is smart enough to share objects between implementing classes. If not, you can construct a MyImplementingClass another way, and then use TheDefaultIs() rather than TheDefaultIsConcreteType().

Related

Autofac: What is the difference between InstancePerRequest and InstancePerLifetimeScope in an MVC app

I am trying to understand lifetime scopes in Autofac IOC and have the following question.
Assume we have class:
public class TestMemLeak
{
SomeDisposableContext cn;
public TestMemLeak(SomeDisposableContext context)
{
cn = context;
}
}
where the injected dependency SomeDisposableContext implements IDisposable.
In an MVC application I get a memory leak when resolving TestMemLeak object if SomeDisposableContext is registered as InstancePerDependency (default option). The leak is gone if I register it as InstancePerRequest or InstancePerLifetimeScope.
I don't understand why InstancePerLifetimeScope fixes the leak. My understanding is that if we resolve dependency from root then InstancePerLifetimeScope should behave in same way as InstancePerDependency, and the solution to problem would be to pass ILifetimeScope to TestMemLeak class and resolve the dependency using lifetime scope. Why is this assumption wrong and what is the difference between InstancePerRequest and InstancePerLifetimeScope in MVC app scenario (apart from InstancePerRequest looks for specific 'httpRequest' lifetime scope)? When should I use InstancePerRequest? It would be great if someone could explain this especially from memory leaks perspective.
As described in the documentation, InstancePerLifetimeScope works for nested resolves. So it means that in your case one object was instantiated for your HTTP request and it gets its dependencies injected and they are all resolved within the same scope. This is basically done by Autofac MVC integration, it is known as BeginLifetimeScope with the HTTP scope tag.
In case your dependency will be instantiated somewhere else, not within the nested resolution three, it will be outside of the lifetime scope and will not be disposed.
InstancePerRequest however is nothing more than the InstancePerMatchingLifetimeScope with predefined tag constant MatchingScopeLifetimeTags.RequestLifetimeScopeTag. Therefore, your dependency does not need to be instantiated inside the nested lifetime scope resolution, it will be enough for the scope with this tag to be open to get the instance attached to this scope.

Call a setup method when first requested in Typhoon Framework

I'm using Typhoon for Dependency Injection with iOS.
I have registered a class, ConfigProviderImpl, that is depended upon by other classes. Basically, I want a method, loadConfig to be called the first time that ConfigProvderImpl is requested by another object.
I've used Dependency Injection in other languages and something like this could usually be solved by making the instance up front, calling the method, and then registering the instance itself with the container so that it was already in the right state. I'm using Typhoon 1.6.9 at the moment and it doesn't seem to have the ability to register instances. I've checked the wiki for 2.0 too and it still doesn't allow this.
At the moment I'm using:
[definition setBeforePropertyInjection:#selector(loadConfig)];
But this is being called every time the class is requested. I realise I could use some dispatch_once magic but I just wondered if there was a cleaner way?
Dependency injection frameworks for other languages are often focused on server-side development. So the default scope for components is singleton. This makes sense, given that a server may need to execute the use-case for any one of its services at a given time.
However in desktop and mobile development, we're typically servicing one use-case at a time. And, particularly on mobile, we have memory constraints at play. Therefore, Typhoon introduces a new memory scope as default - TyphoonScopeObjectGraph. With this scope, any shared references during resolution of a component will return the same instance. This means that:
You can load a whole object graph, including circular dependencies (delegates, etc). For an iOS app, this could typically be a view controller.
After the use-case is complete this object-graph can be discarded and memory reclaimed.
To create a lazy singleton:
Of course, while this is the default, not all components will require this behavior. To make a singleton that isn't instantiated until the first request for it:
definition.scope = TyphoonScopeSingleton;
definition.lazy = YES;
After doing this:
Your callback method will be invoked just once for the singleton.
It won't be executed until the component is used.
There are four scopes in total TyphoonScopeObjectGraph, TyphoonScopePrototype (always returns a new instance), TyphoonScopesingleton and TyphoonScopeWeakSingleton. Further explanation for each of these is available in the Typhoon docs.
Alternative Approach:
Your other approach was to register an object instance in the container. In Typhoon there's not a short-hand way to register a given instance to play some role. However you can inject any object, and you can register a component that will produce other components in the assembly. Therefore we can do the following:
- (id)configProvider
{
return [TyphoonDefinition withClass:[ConfigProvider class]
configuration:^(TyphoonDefinition* definition){
//Typhoon 1.x was more explicit (withDefintion, withBool, withInstance, etc)
//in 2.0 you just use the word 'with'
[definition injectProperty:#selector(config) with:someObject];
}];
}
- (id)config
{
return [TyphoonDefinition withFactory:[self configProvider]
selector:#selector(config)];
//You can also have args here, eg #selector(configForEnv:)
}
The docs for this feature are here.

Inject with different scope when using DbContext with custom resource provider

In an application I have the following components (among others):
MyDbContext : Entity framework data access
DBResourceProviderFactory : A custom ResourceProviderFactory providing a custom IResourceProvider (called DBResourceProvider...)
Other services
StructureMap
The custom resource provider is looking resources up in the db using MyDbContext, injected similarly as described in this SO answer.
The MyDbContext is also used in various other services, and since it is a web application, I use StructureMaps HttpContextScoped method to limit the lifetime of MyDbContext to the lifetime of the request (see an other SO question and its answer on this subject):
x.For<MyDbContext>().HttpContextScoped();
However, it seems that the lifetime of an IResourceProvider is not limited to a single http request. Therefore, DBResourceProvider keeps hanging onto a MyDbContext reference which will be disposed after the first request.
How can I handle this lifetime mismatch - have StructureMap return a transient MyDbContext for IDbResourceProvider while returning HttpContext-scoped instances to all other services?
Do I need two different implementations to do that? A marker interface?
Or is it a bad idea to use Entity Framework to look up localized resources in the first place (performance etc.)?
If you have a service that has (or needs to have) a long lifetime than (one of) its dependencies, the general solution is to use a factory to get those dependencies.
In your situation the solution might be simple. When your DBResourceProvider is defined in your composition root of your MVC application, it would simply succeed to use the DependencyResolver.Current.GetService method to get the MyDbContext.
When the DBResourceProvider service isn't part of the composition root (for instance because it contains business logic that you need to test), you could either extract that logic into its own class, to allow the service to be in the composition root, or you can inject a (singleton) factory (for instance IDbContextFactory or Func<MyDbContext>) that allows you to get the proper instance to be resolved.

Construtor/Setter Injection using IoC in HttpHandler, is it possible?

I've ran into a rather hairy problem. There is probably a simple solution to this but I can't find it!
I have a custom HttpHandler that I want to process a request, log certain info then enter the details in the database. I'm using NUnit and Castle Windsor.
So I have two interfaces; one for logging the other for data entry, which are constructor injected. I quickly found out that there is no way to call the constructor as the default parameterless constructor is always called instead.
So I thought I would use Setter injection and let Castle windsor sort it out. This actually works as when I use container.Resolve<CustomHttpHandler>(); I can check that the logger is not null. (In Application_Start in Global.asax.cs)
The problem is although Castle Windsor can create the instance the http application is not using it??? I think??
Basically the whole reason for doing it this way was to be able to test the logger and data repository code in isolation via mocking and unit testing.
Any ideas how I can go about solving this problem?
Thanks!
Not possible, at least not directly. IHttpHandler objects are instantiated by the ASP.NET runtime and it doesn't allow Windsor to get involved in its creation. You can either:
Pull dependencies, by using the container as a service locator.
Set up a base handler that creates, injects and delegates to your own handlers (see how Spring does it)
Use the container as a service locator for another service that handles the entire request (as saret explained)
What you could do is have the HttpHandler call out to another object that actually handles the request. so in your HttpHandler's ProcessRequest method you would do something like this:
public void ProcessRequest(HttpContext context)
{
var myHandlerObject = container.Resolve<HandlerObject>();
myHandlerObject.ProcessRequest(context or some state/info that is required)
}

Linq to SQL DataContext Windsor IoC memory leak problem

I have an ASP.NET MVC app that creates a Linq2SQL datacontext on a per-web-request basis using Castler Windsor IoC.
For some reason that I do not fully understand, every time a new datacontext is created (on every web request) about 8k of memory is taken up and not released - which inevitably causes an OutOfMemory exception.
If I force garbage collection the memory is released OK.
My datacontext class is very simple:
public class DataContextAccessor : IDataContextAccessor
{
private readonly DataContext dataContext;
public DataContextAccessor(string connectionString)
{
dataContext = new DataContext(connectionString);
}
public DataContext DataContext { get { return dataContext; } }
}
The Windsor IoC webconfig to instantiate this looks like so:
<component id="DataContextAccessor"
service="DomainModel.Repositories.IDataContextAccessor, DomainModel"
type="DomainModel.Repositories.DataContextAccessor, DomainModel"
lifestyle="PerWebRequest">
<parameters>
<connectionString>
...
</connectionString>
</parameters>
</component>
Does anyone know what the problem is, and how to fix it?
L2S DataContext implements IDisposable. Your interface also has to implement it, and call DataContext.Dispose(), so that Windsor knows that there're resources to be disposed.
By the way beware of Windsor/IDisposable problems:
http://www.jeremyskinner.co.uk/2008/05/03/aspnet-mvc-controllers-windsor-and-idisposable/
http://www.nablasoft.com/Alkampfer/?p=105
No your DataContextAccessor does not need to implement IDisposable. Windsor is smart enough to handle the case without having to do any modifications to your classes.
However since as noted in the other answers DataContext does implement it, and Windsor sees it and it registers it for cleanup (to call the Dispose method on it).
What you need to do is to call container.Release and pass your root service (which probably would be DataContextAccessor in your case). Windsor will then release it and all its dependencies (it will also call Dispose on DataContext) and the memory will be freed.
If you're using ASP.NET MVC consider using MVCContrib project which has Windsor integration that handles releasing of components for you.
From what I can tell, queen3 is correct, your DataContextAccessor class needs to implement IDisposable and call datacontext.Dispose() from its .Dispose() method. (Disclaimer: I haven't worked with Castle Windsor.)
Alternatively, what I would do is turn your DataContextAccessor into a DataContextFactory, which only creates the DataContext when you call a method (e.g. GetContext()). Then you can do this:
using(DataContext context = myDataContextFactory.GetContext()) {
// Do whatever you want with the context
}
// Context is disposed here
You might also want to take a look at this previous question: How do you reconcile IDisposable and IoC?
I think #Krzysztof Koźmic is right... you should release whatever you get from Windsor.
Windsor is pretty alien to anyone used to IDisposable. The reason for this apparent disparity is down to the management of the component's lifecycle. If you take a component from Windsor that is IDisposable, you don't know if that instance is configured as transient or a singleton (and of course this could change as your app evolves).
If you dispose a component and it later turns out to be a singleton, some other client code is going to be wondering why its component has suddenly failed!?! Only Windsor is able to make the Disposal decision for you.
Nice blog post Krzysztof (won't let me post link!)
In our app we've made everything transient, apart from a couple of singletons. Transient seems to be the simplest model (as long as everyone understands you must 'Release rather than Dispose'). If you have a mock container in your tests, you can set an expectation that Release is called for each component your mock resolves, and I've also heard that transient has fewer performance issues (??) than other modes? The code is certainly more portable.
Last but not least, if you have a memory leak and you need to work what and why something isn't being collected by the GC, check out Tess Ferrandez' fab tutorial series on windbg
http://blogs.msdn.com/b/tess/archive/2008/04/03/net-debugging-demos-lab-7-memory-leak-review.aspx ... the culprit may be somewhere unexpected!

Resources