Com.MarcusTS.SmartDI 1.0.32

There is a newer version of this package available.
See the version list below for details.
dotnet add package Com.MarcusTS.SmartDI --version 1.0.32                
NuGet\Install-Package Com.MarcusTS.SmartDI -Version 1.0.32                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Com.MarcusTS.SmartDI" Version="1.0.32" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Com.MarcusTS.SmartDI --version 1.0.32                
#r "nuget: Com.MarcusTS.SmartDI, 1.0.32"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Com.MarcusTS.SmartDI as a Cake Addin
#addin nuget:?package=Com.MarcusTS.SmartDI&version=1.0.32

// Install Com.MarcusTS.SmartDI as a Cake Tool
#tool nuget:?package=Com.MarcusTS.SmartDI&version=1.0.32                

Finally, a DI Container Without The Fake "IOC" Swagger

It's just dependency injection - that's all, folks

Modern programmers require some means of creating new classes out of other classes that are passed as parameters, and to do so in an elegant, seamless manner. Those new instances often require caching, especially if they are services or view models. The got-to solution for this challenge has been the mis-named and grossly mis-described "IOC Container". If we can't even name something accurately, it is time to reconsider it entirely. So I have done that here with the tool that all of us actually need: a DI ("Dependency Injection") Container.

What's So Smart About It?

IOC containers always store an instance when you create it. That is extremely wasteful. The Smart DI Container provides only three types of registrations:

1. Any Access Level / Do Not Store

Use these to create instances at any time and without caching. The local variable you retrieve on Resolve() is the only stored reference.

alternate text is missing from this package README image

2. Shared Between Instances

When you Resolve() using this access level, you must to pass in a "parent" object that gets indexed to that new class instance. You can also link the same instance to any number of other consumers/parents by calling Resolve() again. Once all of the parents die, the cached instance is also removed.

Note: This requires you to raise the ObjectDisappearingMessage to notify the container about the death of a shared instance parent. That message is declared in our Shared Forms Library, which you can import from Nuget.

We can do this for you if you also use our a few other simple libraries:

LifecycleAware. NuGet.

SmartDI.LifecycleAware. NuGet.

There's also a handy sample app here and on Nuget.

In spite of the ginormous size of other containers on the market, none of them can pass this test. The container must provide a physical mechanism to make this functionality possible. We have one!

3. Global Singleton

The container creates and caches a permanent instance of any type registered with this access level. The cached reference dies when the container itself falls out of scope.

alternate text is missing from this package README image

The Smart DI Container is Not inherently global or static

You can declare an instance of the Smart DI Container wherever you please. This supports "nested" scenarios, where containers live within narrowly defined class inheritance trees. Remember: all "global" variables stored/cached will only live as long as the container does.

The Smart DI Container is well-behaved

This container protects against recursive calls, or any other violation of the rules-based registrations you make. For instance, if you register two competing interfaces for the same base type:

_container = new SmartDIContainer();
_container.RegisterTypeAsInterface<FirstSimpleClass>(typeof(IAmSimple));
_container.RegisterTypeAsInterface<SecondSimpleClass>(typeof(IAmSimple));

... and then resolve IAmSimple, you have created a conflict. The container cannot know which one to return. You can set a Boolean property to throw an error in this case. Or you can provide a conflict resolver:

var simple = 
   _container.Resolve<IAmSimple>(
      StorageRules.AnyAccessLevel, null, ForbidSpecificClass<FirstSimpleClass>);

private static IConflictResolution ForbidSpecificClass<T>(
   IDictionary<Type, 
   ITimeStampedCreatorAndStorageRules> registrations)
{
   // Find any registration where the key 
   //    (the main class that was registered and that is being constructed) 
   //    is *not* the forbidden one
   var legalValues = registrations.Where(r => r.Key != typeof(T)).ToArray();

   if (legalValues.IsEmpty())
   {
      return null;
   }

   return 
      new ConflictResolution
         {
            MasterType                = legalValues.First().Key,
            TypeToCastWithStorageRule = 
               legalValues.First().Value.CreatorsAndStorageRules.First()
         };
   }
}

The Smart DI Container is tiny

It occupies almost no space at all, and rarely touches memory, since it does not store anything unnecessarily.

The Smart DI Container is open source C#, and easy to read.

We actually added comments! (And we were not struck by lightning)

The Smart DI Container is tested and proven

See the unit tests.

Other Resources

Please also refer to the Quick Start Guide.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Com.MarcusTS.SmartDI:

Package Downloads
Com.MarcusTS.PlatformIndependentShared

Platform independent utilities for C# development.

Com.MarcusTS.UI.XamForms

Xamarin.Forms abstract classes and utilities to support creating flowable animated apps.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2.0.5 1,023 7/30/2022
2.0.4 435 7/29/2022
2.0.2 1,937 10/29/2021
2.0.1 628 10/28/2021
1.0.39 388 10/28/2021
1.0.37 434 8/27/2021
1.0.36 368 8/24/2021
1.0.35 449 8/24/2021
1.0.34 681 8/17/2021
1.0.32 699 8/15/2021
1.0.31 601 8/10/2021
1.0.30 381 8/10/2021
1.0.29 386 8/10/2021
1.0.28 900 7/6/2021
1.0.27 924 6/24/2021
1.0.24 994 4/7/2021
1.0.23 544 4/1/2021
1.0.22 611 1/30/2021
1.0.21 498 10/29/2020
1.0.20 493 10/29/2020
1.0.19 861 10/28/2020
1.0.18 793 10/28/2020
1.0.17 895 4/22/2020
1.0.16 1,242 10/26/2019
1.0.15 649 7/30/2019
1.0.14 990 6/10/2019
1.0.13 724 6/10/2019
1.0.12 1,049 3/12/2019
1.0.11 743 1/7/2019
1.0.10 811 12/28/2018
1.0.9 831 12/27/2018
1.0.8 739 12/26/2018
1.0.7 729 12/25/2018
1.0.5 720 12/24/2018
1.0.4 743 12/24/2018