IoC container and dll memory management - c#

I'm working on a server project and the server has a few different, independent layers and a few singleton classes. And I use the SimpleInjector, an IoC container, all across the layers. The full, executable example source code is available at https://github.com/DamonJung/TestAdvanture001.. ( It's unnecessarily lengthy because I was trying to reproduce a different problem there. )
I access the Singleton from Main method directly and indirectly from the IoC container.
// Use case in Main
.
.
using Impl;
static void Main(string args[])
{
.
.
// Singleton.Instance address = 0x0301f001 for example.
var context = Singleton.Instance.GetContext();
// SimpleInjector
// Singleton.Instance address inside of the dependency = 0x0408f023 for example.
var di = Container.GetInstance<ISomeInterface>();
var contextFromIoC = di.GetContext();
.
.
}
I expected the Singleton should be instantiated only once and the static instance should have the exact same memory address in the application, no matter where it's being invoked from and no matter how it's constructed ( by Main or the IoC container )
However, as the console output is saying, it didn't work that way. The Singleton's Instance shouldn't have been instantiated more than once. But they ended up having a different address on their own.
If my shallow understanding serves me right, the executable loads the dll into its own memory, and once the static member is created, the variable can be accessed throughout the AppDomain region.
Isn't this confirming the fact about static variables, isn't it?
Static Members
A non-static class can contain static methods, fields, properties, or events. The static member is callable on a class even when no instance of the class has been created. The static member is always accessed by the class name, not the instance name. Only one copy of a static member exists, regardless of how many instances of the class are created. Static methods and properties cannot access non-static fields and events in their containing type, and they cannot access an instance variable of any object unless it is explicitly passed in a method parameter.
I was in search for the relevant read in SimpleInjector's documentation and found none. Reading about dynamic linking library and its memory management doesn't come right at me ( I shall be reading it further and over and over again anyway ! )
How a program treats dlls in terms of memory management
If IoC container is the scene behind, how SimpleInjector treats the dependencies when they are registered via Container.Register();
Above items would be my ultimate questions.

Two instances are created because your code creates two instances.
The first one is created by the following code
public class Singleton
{
public static readonly Singleton Instance = new Singleton();
// ....
}
and the second one is created when you register your type to SimpleInjector
If you want an instance to be created only once you could use a private constructor
public class Singleton
{
static Singleton()
{
Singleton.Instance = new Singleton();
}
public static Singleton Instance { get; }
private Singleton(){
}
}
This way only the Singleton class create itself.
To register your singleton in SimpleInjector you can use the RegisterInstance method :
container.RegisterInstance<Singleton>(Singleton.Instance);
By the way it is more common to let the container manage instances by itself and not rely on static property which could indicate that you are using a service locator which is a common anti pattern.
If you want to let SimpleInjector manage the instance you should use
container.RegisterSingleton<Singleton>();
This way SimpleInjector will create only one Singleton instance for the container.
See Singleton lifestyle in the SimpleInjector documentation

Related

Limited singleton lifetime determined by another object

This may be something to be solved with Autofac nested scopes, but I have not been able to make enough of the documentation to figure it out myself.
I think what I am looking for is like a per-HTTP-request singleton, but the place of the request is taken by the lifetime of another object.
There is a class SubSystem, of which a new instance is created (resolved from the container, potentially through a factory class) every time new data is loaded into the application (the old data and SubSystem instance are discarded).
Then there are classes SomeFeature, implementing IFeature, and SomeService, implementing ISomeService.
SubSystem has dependencies on both IFeature and IService, while SomeFeature takes a dependency on IService. So the object graph looks like this:
SubSystem
└> SomeService : IService <─┐
└> SomeFeature : IFeature ├─── same instance
└> SomeService : IService <─┘
IFeature is only required in one place, so a transient registration is fine here. IService on the other hand must be resolved to the same instance for all dependencies within this subgraph, but when new data is loaded and a new SubSystem instance is created, its subgraph must get its own new "per-request singleton" IService instance.
The reason for discarding the instances is that they cache information from the loaded data for performance reasons, which will not be valid anymore when new data is loaded. I am currently using real singleton instances that have their local state reset via an event raised in the SubSystem constructor, but that is clearly a less than optimal solution.
As I said, I'd like this to work like InstancePerHttpRequest(), but as "instance per SubSystem".
Is there a way to achieve this using the Autofac API?
The option I think you're looking for is:
.InstancePerOwned<SubSystem>()
If you only consume SubSystem in one place, just take a dependency on Owned<SubSystem> at that point, and make sure you Dispose() the Owned<T> in the consuming component's Dispose() method.
For something a bit more transparent, assuming you can create ISubSystem to go with SubSystem you can do this:
builder.RegisterType<SubSystem>()
.InstancePerOwned<SubSystem>();
builder.RegisterType<SubSystemGraph>()
.As<ISubSystem>()
// Appropriate sharing here...
;
Where SubSystemGraph is:
class SubSystemGraph: ISubSystem, IDisposable
{
readonly Owned<SubSystem> _root;
public SubSystemGraph(Owned<SubSystem> root)
{
_root = root;
}
public void Dispose()
{
_root.Dispose();
}
// Methods of ISubSystem delegate to _root.Value
public void Foo()
{
_root.Value.Foo();
}
}
(This could be packaged up into a nicer interface on Autofac but it's not all that common in practice.)

Can static properties return new instances of objects/classes in c#

I am building an application in ASP.NET MVC 4. I am creating a class (similar to Factory type) that will return me instance of my service classes which i have made in BAL Layer. I want to declare static properties in that class and they should return Instance of requested Service Class.
My question is that is it possible that a static propery will return instance of new class because static property will be allocated a memory that will remain throughout the application. I am little confused here, Please explain what happens and what is best way to do so.
Code done so far
public class Factory
{
public static CountryService CountryServiceInstance
{
get
{
return new CountryService(new CountryRepository());
}
}
}
What you should do is write a function the will create the new instances not a get property
public class Factory
{
public static CountryService CreateNewService()
{
return new CountryService(new CountryRepository());
}
}
About your memory concern read Sriram Sakthivel's first comment
More about the Factory pattern here:
http://msdn.microsoft.com/en-us/library/ee817667.aspx
A property in C# is just a method which returns what it should return in its body. In your case, each time you access that property, a new instance of the service will be created.
In case you want only one instance of that service, you might want to store it to the static private variable like this
private static readonly Lazy<CountryRepository> _fact
= new Lazy<CountryRepository>(() => new CountryRepository());
Also, a static properlty never stores something "in the memory throughout the application", but a programmer can do that.
Once again, a property is just a pair of set\get methods, unless you use an automatic property, where there is also a backing field created for the value to store.
A static keyword itself only specifies that a current class member must not be accessed though this keyword, and its value will be shared all across the appdomain (or your application).
your method CountryServiceInstance for each call will always gives you a new instance of CountryRepository.
As you have mentioned, Most of the Factory classes are static which are responsible for creating new object instances. If they give the same object instance none of the factory patterns will serve its intent.
you can undoubtedly proceed with your sinppet..
if you want to quickly validate you can check the created objects hashcode
object.GetHashCode() they will be unique as they are separate objects

Resolve type with IoC Container from within static Method

When using an IoC container without a static container instance (as this would result in a a service locator anti-pattern), how to resolve types from a static method?
Say, I have a method that reads an object Document from a file:
public class Document {
// when used with IoC, the Logger gets injected via property injection
public ILogger Logger { get; set; }
/* ... */
public static Document Read (string filePath)
{
// need to resolve an ILogger at this point?
Logger.Info ("reading in {0}", filePath);
/* ...read in document an return a document instance here ... */
}
}
The Code is C# but same problem would apply to a Java project.
I know that a simple answer would be "don't use static method", but given the method is stateless i think it is one of the cases where static methods make sense.
Having a singleton IoC container would also help, but this is widely known to be an anti-pattern.
So, what is the way out of the problem?
Although, I can understand why this makes sense to write this function as static, the answer is simply that DI is not going well with static methods that have an associated state. Injected properties are a state of the object and static methods that have an associated state are considered to be an anti-pattern.
DI sometimes forces you to use pure (not anti) patterns.
If you insist on using static method in your case, I can suggest these to cover your options. All are not perfect.
Adding the injected objects as parameters to the function.
Document.Read(logger, filePath).
If you weren't using an IoC framework, the alternative was:
new Document(logger).Read(filepath)
which is more or less, the same clumsy code for the caller.
Using a ServiceLocator as you stated.
Add a static initialization method to the class, and inject all of it's dependencies (as static properties). You would have to call this initialization in your application start.

Do I need to use synclock with objects managed by a DI container using singleton scope?

I have the following code:
public class DotLessFactory
{
private LessEngine lessEngine;
public virtual ILessEngine GetEngine()
{
return lessEngine ?? (lessEngine = CreateEngine());
}
private ILessEngine CreateEngine()
{
var configuration = new LessConfiguration();
return new LessFactory().CreateEngine(configuration);
}
}
Let's assume the following:
I always want the same instance of ILessEngine to be returned.
I use a DI container (I will use StructureMap for this example) to manage my objects.
The lifetime of my objects will be Singleton because of assumption number 1.
The code inside CreateEngine executes code that is referenced through a NuGet package.
DotLess is a mere example. This code could be applicable to any similar NuGet package.
Approach 1
I register my objects with my DI container using:
For<DotLessFactory>().Singleton().Use<DotLessFactory>();
For<ILessEngine>().Singleton().Use(container => container.GetInstance<DotLessFactory>().GetEngine());
For<ISomeClass>().Singleton().Use<SomeClass>();
Now I can add ILessEngine to a constructor and have my container inject an instance of it as per the code below.
public class SomeClass : ISomeClass
{
private ILessEngine lessEngine;
public SomeClass(ILessEngine lessEngine)
{
this.lessEngine = lessEngine;
}
}
Approach 2
Introduce an IDotLessFactory interface which exposes the GetEngine method. I register my objects with my DI container using:
For<IDotLessFactory>().Singleton().Use<DotLessFactory>();
For<ISomeClass>().Singleton().Use<SomeClass>();
Now my factory will create an instance of ILessEngine as per the code below.
public class SomeClass : ISomeClass
{
private ILessEngine lessEngine;
public SomeClass(IDotLessFactory factory)
{
Factory = factory;
}
public IDotLessFactory Factory { get; private set; }
public ILessEngine LessEngine
{
get
{
return lessEngine ?? (lessEngine = Factory.GetEngine());
}
}
}
My questions are:
What is the fundamental difference between Approach 1 and 2 when it comes to ILessEngine? In approach 1 the ILessEngine is managed by the container and in approach 2 it is not. What are the upside/downside to each approach? Is one approach better than the other?
Do I need to use a synclock inside the CreateEngine method to ensure thread safety for any of the approaches? When should/shouldn't I use synclock in a scenario like this?
I have seen examples where Activator.CreateInstance is used inside the CreateEngine method as opposed to newing up the object directly. Is there a reason one would use this approach? Has this something to do with not introducing direct dependencies in the factory object to objects inside the NuGet package?
Let's assume the referenced NuGet package works with HttpContext under the hood. Would registering my factory in singleton scope have any negative effect on HttpContext or does that not matter since I assume the NuGet package most likely manages the scope of HttpContext itself?
Finally, the DotLessFactory will eventually be used with Bundles (Microsoft.AspNet.Web.Optimization NuGet package) and the Bundle is only instantiated (not managed by container) on Application Start. The Bundle will depend on an injected instance of DotLessFactory. Does this fact make any difference to the questions above?
Any feedback would be extremely helpful.
It's non-trivial to answer these questions specifically, but allow me to provide some non-exhaustive comments:
As far as I can tell, none of the approaches guarantee requirement #1 (singleton). This is because two threads could perform a look-up at the same time and both evaluate lessEngine to null and trigger the creation of a new instance. The first approach may end up being thread safe if StructureMap lookups are thread safe, but I'd be surprised if this was the case (and regardless, you do not want your code to depend on an implementation "detail" in a 3rd party library).
Both solutions make the same mistake, which is essentially checking whether an instance has already been created without protecting the entire code region. To solve the problem, introduce a private object variable to lock on, and protect the code region creating the instance:
private object engineLock = new object();
public virtual ILessEngine GetEngine()
{
lock( engineLock ) { return lessEngine ?? (lessEngine = CreateEngine()); }
}
As an aside, this would not be necessary if you could make StructureMap handle construction of the entire object chain, as it would then be up to StructureMap to ensure the singleton requirement as per your configuration of the container.
You can only new objects if you know they have a default constructor (e.g. through a generic constraint in the code for a type parameter) or you have a compile-time reference to them. Since an IoC mostly creates things it didn't know about at compile time, and it often needs to pass parameters when doing so, Activator.CreateInstance is used istead. As far as I know, using "new" generates IL to invoke Activator.CreateInstance, so the end result is all the same.
The lifetime of HttpContext is managed outside of your application (by ASP.NET) and so there is no scoping issue. HttpContext.Current will either be set or not, and if it isn't then you're doing work too early for it to be available (or executing in a context where it is never going to be available, e.g. outside ASP.NET).
Uh, not sure what potential problem you're considering here, but my best guess is that it shouldn't have any effect on your code.
Hope this helps!

How do i handle static classes while using IOC

I just started migrating my web application to fully use Windsor IOC. Here is a little problem I am encountering;
I have couple of static classes which I used to store some application level global values
EG (Simplified version of the class):
public static class SiteInfo
{
public static Language Language = (Language)byte.Parse(SiteInfo.Val("language"));
public static string Code = Site.Code;
public static string Name = Site.Name;
public static SiteCachedData CachedData { get; set; }
public static Site Site { get; set; }
public static void Init()
{
//Get site info from DB here
//I need to inject _SiteRepository here but I can't
//since I don't have access to the constructor
}
}
I am new to IOC and I understand static classes are advised to be prevented. What is the good practice to handle this situation? I am thinking of converting this to a singleton but I am not sure if that is my best bet.
This is one of the reasons why I like to avoid static classes --they are hard to inject or invert control. They usually have to know intimate details of several low level classes. Since they are static classes you can leave them because they are already available to all of the other classes and don't require injection.
One trick that I've done is to create a second class that delegates into the static class. You can then put an interface onto the new class and get into an IoC framework easier.
public static class StaticClass
{
public static object Method()
}
public class NonstaticClass : INewInterface
{
public object Method()
{
return StaticClass.Method();
}
}
The good part of this refactor is that you can go method by method and then determine new objects and interfaces as you go. Eventually you may be able to get rid of the original static class. You would also register the new classes as singleton instances so that only one instance exists at a time.
In the context of an IoC container, it's a bit ambiguous to say 'convert it to a singleton'. If you mean the singleton design pattern, you probably shouldn't do it that way, as there are better alternatives in the IoC world.
IoC containers perform two main roles: to resolve dependencies between components, and to manage the lifetime of components. A container manages the lifetime of its components by deciding when to create and destroy component instances.
For example, when you call container.Resolve<SiteInfo>(), the container has to decide whether to re-use an existing SiteInfo instance or create a new one. How does the container decide? Well, when you register SiteInfo with the container, you can tell the container how you would like it to behave. If you register it as a Singleton, the container will only create a SiteInfo instance on the first call to container.Resolve<SiteInfo>(); on subsequent calls, it re-uses the existing SiteInfo instance.
The advantage of this technique over the singleton pattern is flexibility. If you use the design pattern, your SiteInfo class will forever be a singleton (unless you refactor). By using the container to manage the lifetime, you can change your mind later and just change the container registration code. Consumers of the component don't need to (and shouldn't) care whether the container provides them with a new instance or re-uses an existing one - they just call container.Resolve().
I'm not familiar with Windsor (I use Autofac), but it looks like you have two ways of registering a component as a singleton (I'm sure someone will correct me if this is wrong):
container.AddComponentLifeStyle<SiteInfo>(LifestyleType.Singleton)
or,
container.Register( Component.For<SiteInfo>()
.LifeStyle.Singleton );
However, a word of warning. In your example, your SiteInfo class has a dependency on the _SiteRepository class. You will therefore also need to register a _SiteRepository instance as a singleton in the container, so that it is available when the container resolves the SiteInfo. This _SiteRepository instance will remain in memory for the lifetime of the container, i.e. for the lifetime of the Web application, because it's a singleton. If the repository keeps a DB connection open, therefore, that connection will remain open for the same lifetime.
For this sort of reason, an alternative lifestyle is per-web-request - in other words, the container will create a new instance of your SiteInfo class once per web request. The per-web-request lifestyle is discussed in another question.
You can register an single instanec of a class in your container, so it behaves like a singleton. The container gives you the same instance every time.

Categories

Resources