Releases: seesharper/LightInject
v5.1.8
Change Log
v5.1.8 (8/23/2018)
Full Changelog
Merged Pull Requests
Fully implement the Clone method. Fixes #396 (8/23/2018) #437 (seesharper)
Closed Issues
v5.1.7
Change Log
v5.1.7 (8/21/2018)
Full Changelog
Merged Pull Requests
Performance/reuse delegates (8/21/2018) #436 (seesharper)
Improves memory usage by reusing the generated GetInstanceDelegate
.
Thanks to @leandro86 for coming up with such a simple and effective solution. 👍
Closed Issues
- Issues implementing a ILifetime for Session (SessionLifetime) (8/17/2018) #95 (zhech2)
- Resolving of IEnumerable when IService instances registered with explicit registration. (8/20/2018) #424 (dmitryshunkov)
- Challenge (Help wanted) Possible memory problem (8/21/2018) #434 (seesharper)
v5.1.6
Change Log
v5.1.6 (8/7/2018)
Full Changelog
Merged Pull Requests
Bugfix/named collections (8/7/2018) #433 (seesharper)
Fixes a bug that caused named collections to yields an empty result.
seesharper/LightInject.Microsoft.DependencyInjection#27
Closed Issues
- Struggling with strange recursive dependency (7/23/2018) #430 (adyshimony)
- Recursive dependency detected on ObservableCollection (7/25/2018) #431 (adyshimony)
v5.1.5
Change Log
v5.1.5 (7/5/2018)
Full Changelog
Merged Pull Requests
Fixed assembly file version (7/5/2018) #425 (seesharper)
Sets the assembly file version.
Enabled tests (7/5/2018) #426 (seesharper)
Enabled tests again
v5.1.4
Change Log
v5.1.4 (6/24/2018)
Full Changelog
Merged Pull Requests
Tests/decorators (5/17/2018) #418 (seesharper)
Added a new decorator test and use new C# language features across the code base.
Better support for Microsoft.Extensions.DependencyInjection (6/23/2018) #420 (seesharper)
This PR adds a couple of changes related to the Microsoft.Extensions.DependencyInjection
integration.
- Allow changing the default service convention using
ContainerOptions.DefaultServiceSelector
- Add
netcoreapp2.0
target so that we can useSystem.Reflection.Emit.LightWeight
on .Net Core - Ensure that we dispose services in reverse of their creation.
Include pull request body in release notes (6/24/2018) #421 (seesharper)
Ensure that we include the pull request body when generating release notes.
Build/artifacts (6/24/2018) #422 (seesharper)
Added Artifacts
folder to .gitignore
file
Closed Issues
- Parallel scopes (5/16/2018) #112 (seesharper)
- Change Log Missing? (5/17/2018) #272 (pagebrooks)
- NServiceBus Support (5/17/2018) #279 (joefeser)
- ICompositionRoot only works in .net framework, not .net core (5/17/2018) #358 (philippe-lavoie)
- HttpContext.current is null when creating scope in LightInject.web (5/17/2018) #388 (karunagoyal)
- RegisterAssembly with search pattern no more available? (5/17/2018) #389 (leorjbrz)
- Memory Leak (5/16/2018) #400 (aydany)
- PerScopeLifetime in webapi is not working (5/17/2018) #402 (asafp)
- Register Singleton lifetime (5/9/2018) #415 (lutaiphong)
- Intercept action controller with arguments in mvc 5 throw exception (6/5/2018) #419 (zu1779)
5.1.3
Change Log
v5.1.3 (08.05.2018)
Full Changelog
Merged Pull Requests
Remove zero width space... (26.03.2018) #410 (kreediam)
(\u200b) which breaks code formatting
Feature/Compilation (08.05.2018) #412 (seesharper)
This PR adds support for compiling delegates up front.
Initial docs
Compilation
LightInject uses dynamic code compilation either in the form of System.Reflection.Emit or compiled expression trees. When a service is requested from the container, the code needed for creating the service instance is generated and compiled and a delegate for that code is stored for lookup later on so that we only compile it once. These delegates are stored in an AVL tree that ensures maximal performance when looking up a delegate for a given service type. If fact, looking up these delegates is what sets the top performing containers apart. Most high performance container emits approximately the same code, but the approach to storing these delegates may differ.
LightInject provides lock-free service lookup meaning that no locks are involved for getting a service instance after its initial generation and compilation. The only time LightInject actually creates a lock is when generating the code for a given service. That does however mean a potential lock contention problem when many concurrent requests asks for services for the first time.
LightInject deals with this potential problem by providing an API for compilation typically used when an application starts.
The following example shows how to compile all registered services.
container.Compile();
One thing to be aware of is that not all services are backed by its own delegate.
Consider the following service:
public class Foo
{
public Foo(Bar bar)
{
Bar = bar;
}
}
Registered and resolved like this:
container.Register<Foo>();
container.Register<Bar>();
var foo = container.GetInstance<Foo>();
In this case we only create a delegate for resolving Foo
since that is the only service that is directly requested from the container. The code for creating the Bar
instance is embedded inside the code for creating the Foo
instance and hence there is only one delegate created.
We call Foo
a root service since it is directly requested from the container.
In fact lets just have a look at the IL generated for creating the Foo
instance.
newobj Void .ctor() // Bar
newobj Void .ctor(LightInject.SampleLibrary.IBar) //Foo
What happens here is that a new instance of Bar
is created and pushed onto the stack and then we create the Foo
instance. This is the code that the delegate for Foo
points to.
The reason for such a relatively detailed explanation is to illustrate that we don't always create a delegate for a given service and by simply doing a container.Compile()
we might create a lot of delegates that is never actually executed. Probably no big deal as long as we don't have tens of thousands of services, but just something to be aware of.
LightInject does not attempt to identify root services as that would be very difficult for various reasons.
We can instead use a predicate when compiling services up front.
container.Compile(sr => sr.ServiceType == typeof(Foo));
Open Generics
LightInject cannot compile open generic services since the actual generic arguments are not known at "compile" time.
We can however specify the generic arguments like this:
container.Compile<Foo<int>>()
LightInject will create a log entry every time a new delegate is created so that information can be used to identify root services that could be compiled up front. In addition to this, a log entry (warning) is also created when trying to compile an open generic service up front.
Use instance lock instead of static lock (Scope) (08.05.2018) #413 (seesharper)
This PR addresses #411 and changes the lock used inside the Scope
class from a static lock to an instance lock
Bumped to 5.1.3 for release (08.05.2018) #414 (seesharper)
This PR bumps the version to 5.1.3
Closed Issues
- Access information about resolved service dependencies (10.03.2018) #397 (ilyazolotarov)
- Recommended way of implementing Custom lifetime using TTL logic? (03.03.2018) #401 (MedAnd)
- Unable to resolve type: Model.Ejercicios.Patrones.IFoo, service name: (02.02.2018) #406 (Byron2016)
- Question: RegisterConstructorDependency for Generics? (07.02.2018) #408 (Mike-EEE)
- Why is there a static/global lock on a lightinject Scope (08.05.2018) #411 (Kadajski)