### Module Registration Example Source: https://github.com/yairhalberstadt/stronginject/wiki/Registration/ModuleRegistration Demonstrates registering modules and inheriting from a module to compose dependencies. Shows how to use `RegisterModule` and handle exclusions. ```csharp using StrongInject; public class A { } public class B { public B(A a) { } } public class C { public C(B b, int i) { } } [Register(typeof(A))] public class ModuleA { } [Register(typeof(A), Scope.SingleInstance)] [Register(typeof(B))] public class ModuleB { } public class ModuleC { private int _i; public ModuleC(int i) => _i = i; protected C CreateC(B b) => new C(b, _i); } [RegisterModule(typeof(ModuleA))] [RegisterModule(typeof(ModuleB), typeof(A))] // Have to exclude A, as otherwise we will have multiple conflicting registrations for A public partial class Container : ModuleC, IContainer // By inheriting from ModuleC we import the protected method CreateC { public Container(int i) : base(i) { } } ``` -------------------------------- ### Container Registration and Resolution Example Source: https://github.com/yairhalberstadt/stronginject/wiki/Resolution Demonstrates a basic container setup with registered types A, B, and C, illustrating the recursive resolution of dependencies. StrongInject resolves A, which requires B, which requires C. ```csharp using StrongInject; [Register(typeof(A))] [Register(typeof(B))] [Register(typeof(C))] public class MyContainer : IContainer() {} public class A { public A(B b){} } public class B { public B(C c){} } public class C {} ``` -------------------------------- ### Runtime Configuration with Instance Fields Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Use `[Instance]` fields to access runtime information during resolution. This example shows how to provide a `Configuration` object to a class `A`. ```csharp using StrongInject; public class A { public A(Configuration configuration){} } public class Configuration {} [Register(typeof(A))] public partial class Container : IContainer { [Instance] Configuration _configuration; public Container(Configuration configuration) => _configuration = configuration; } ``` -------------------------------- ### Decorator Factory Method Registration Example Source: https://github.com/yairhalberstadt/stronginject/wiki/Registration/DecoratorFactoryRegistration Demonstrates registering a decorator factory method to order an array of I instances by priority in descending order. This example shows how to use the factory to influence the resolution of an array of services. ```csharp using StrongInject; using System; using System.Linq; public interface I { public int Priority { get; } } public class A : I { public int Priority => 1; } public class B : I { public int Priority => 2; } [Register(typeof(A), typeof(I))] [Register(typeof(B), typeof(I))] public partial class Container : IContainer { [DecoratorFactory] I[] OrderIArray(I[] iArray) => iArray.OrderByDescending(x => x.Priority).ToArray(); } var container = new Container(); container.Run(x => { Console.WriteLine(x[0].GetType().ToString()); // prints "B" Console.WriteLine(x[1].GetType().ToString()); // prints "A" }); // Resolves a new instance of I[], by resolving an instance of `A` and `B` and putting them in the array. Then calls OrderIArray with this instance, and uses the returned instance as the final resolution of `I[]`. ``` -------------------------------- ### Instance Registration Example Source: https://github.com/yairhalberstadt/stronginject/wiki/Registration/InstanceRegistration Demonstrates registering instances using the [Instance] attribute. Shows both public static module registration with Options.DoNotDecorate and private instance field registration. ```csharp using StrongInject; using System; public class A { } public class B : IDisposable { public void Dispose() { } } // Dispose will never be called public class C { public C(A a, B b) { } } public class Module { [Instance(Options.DoNotDecorate)] public static readonly B _b = new B(); // Must be public and static. } [Register(typeof(C))] [RegisterModule(typeof(Module))] public partial class Container : IContainer { [Instance] private readonly A _a; // Can be private and instance. public Container(A a) => _a = a; } ``` -------------------------------- ### Decorator Factory Method Example Source: https://github.com/yairhalberstadt/stronginject/blob/main/docs/Registration/DecoratorFactoryRegistration.md Demonstrates registering a decorator factory method to order an array of 'I' instances by priority in descending order. This example shows how a factory method can manipulate resolved instances before they are returned. ```csharp using StrongInject; using System; using System.Linq; public interface I { int Priority { get; } } public class A : I { public int Priority => 1; } public class B : I { public int Priority => 2; } [Register(typeof(A), typeof(I))] [Register(typeof(B), typeof(I))] public partial class Container : IContainer { [DecoratorFactory] I[] OrderIArray(I[] iArray) => iArray.OrderByDescending(x => x.Priority).ToArray(); } var container = new Container(); container.Run(x => { Console.WriteLine(x[0].GetType().ToString()); // prints "B" Console.WriteLine(x[1].GetType().ToString()); // prints "A" }); // Resolves a new instance of I[], by resolving an instance of `A` and `B` and putting them in the array. Then calls OrderIArray with this instance, and uses the returned instance as the final resolution of `I[]`. ``` -------------------------------- ### StrongInject Type Registration Example Source: https://github.com/yairhalberstadt/stronginject/wiki/Registration/TypeRegistration Demonstrates registering types A, B, and C with different scopes and registration targets. Shows how StrongInject resolves dependencies and manages disposal. ```csharp using StrongInject; using System; public class A : IDisposable { public void Dispose() { } } public class B : IDisposable { public void Dispose() { } } public interface I { } public class C : I { public C(A a, B b) { } } [Register(typeof(A), Scope.SingleInstance)] // No types specified for `registerAs`, will be registered as type `A`. [Register(typeof(B))] // No `scope` specified, Scope will be InstancePerResolution. No types specified for `registerAs`, will be registered as type `B`. [Register(typeof(C), typeof(C), typeof(I))] // No `scope` specified, Scope will be InstancePerResolution. Registered as type `C` and as type `I`. public partial class Container : IContainer { } var container = new Container(); container.Run(x => Console.WriteLine(x.ToString())); // Will create a new instance of `C` which is registered as `I`, and new instances of `A` and `B` to satisfy `C`'s constructor. `B` will be disposed once the lambda completes. container.Run(x => Console.WriteLine(x.ToString())); // Will create a new instance of `C` which is registered as `I`, and new instances of `B` to satisfy `C`'s constructor. The instance of `A` will be reused from the previous invocation, since it is SingleInstance. `B` will be disposed once the lambda completes. container.Dispose(); // Will dispose the single instance of `A`. ``` -------------------------------- ### Generic Factory Method with FactoryOfAttribute Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md This example demonstrates a generic factory method that is restricted to resolving ILogger and IConfiguration types using the FactoryOfAttribute. It utilizes IServiceProvider to get the required services. ```csharp public partial class AspNetCoreControllerContainer : IContainer { private readonly IServiceProvider _serviceProvider; public AspNetCoreControllerContainer(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } [FactoryOf(typeof(ILogger<>), FactoryOf(typeof(IConfiguration))] private T GetService() => _serviceProvider.GetRequiredService(); } ``` -------------------------------- ### Decorator Registration and Usage Example Source: https://github.com/yairhalberstadt/stronginject/wiki/Registration/DecoratorTypeRegistration Demonstrates how to register a service, a logger, and a decorator for the service using StrongInject. It shows how the decorator intercepts calls and logs messages. ```csharp using StrongInject; using System; public interface IService { string GetMessage(); } public class Service : IService { public string GetMessage() => "Hello World"; } public class ServiceDecorator : IService { private readonly IService _impl; private readonly Logger _logger; public ServiceDecorator(IService impl, Logger logger) => (_impl, _logger) = (impl, logger); public string GetMessage() { var message = _impl.GetMessage(); _logger.Log("Message was " + message); return message; } } public class Logger { public void Log(string str) => Console.WriteLine(str); } [Register(typeof(Service), typeof(IService))] [Register(typeof(Logger))] [RegisterDecorator(typeof(ServiceDecorator), typeof(IService))] public partial class Container : IContainer {} var container = new Container(); container.Run(x => Console.WriteLine(x.GetMessage())); // Will create a new instance of Service and Logger, and pass them as parameters to the ServiceDecorator constructor. The instance of ServiceDecorator will be used as the parameter to the lambda. ``` -------------------------------- ### Factory Method Registration Example Source: https://github.com/yairhalberstadt/stronginject/wiki/Registration/FactoryMethodRegistration Demonstrates registering factory methods for different types, including a generic factory method with a type parameter substitution. Shows how scope affects instance creation. ```csharp using StrongInject; using System; using System.Collections.Generic; public class A { } public partial class Container : IContainer> { [Factory(Scope.SingleInstance)] private A CreateA() => new A(); // Registration for A [Factory] private List CreateList(T t) => new List { t }; // Registration for List by substituting T for A [Factory] private List CreateList() where T : struct => new List { new T() }; // Not a registration for List because substituting T for A does not match the struct constraint } var container = new Container(); container.Run(x => Console.WriteLine(x.ToString())); // Resolves a new instance `A` by calling CreateA(), and calls CreateList(A) with it as a parameter. container.Run(x => Console.WriteLine(x.ToString())); // Reuses the single instance of `A`, and calls CreateList(A) with it as a parameter. ``` -------------------------------- ### Factory Registration Example Source: https://github.com/yairhalberstadt/stronginject/wiki/Registration/FactoryTypeRegistration Demonstrates registering a Factory class as a single instance provider for type A, with A instances created per resolution. Shows how the container manages factory and instance lifecycles, including disposal. ```csharp using StrongInject; using System; public class A : IDisposable { public void Dispose() { } } public class Factory : IFactory, IDisposable { public A Create() => new A(); public void Dispose() { } public void Release(A instance) => instance.Dispose(); } [RegisterFactory(typeof(Factory), Scope.SingleInstance, Scope.InstancePerResolution)] public partial class Container : IContainer { } var container = new Container(); container.Run(x => Console.WriteLine(x.ToString())); // Will create a new instance of Factory. Will call Factory.Create() to create an instance of A. After the lambda completes, will call factory.Release() to dispose of the instance of A. container.Run(x => Console.WriteLine(x.ToString())); // Will reuse the existing instance of Factory since it is SingleInstance. Will call Factory.Create() to create an instance of A since it is InstancePerResolution. After the lambda completes, will call factory.Release() to dispose of the instance of A. container.Dispose(); // Will dispose of the single instance of Factory ``` -------------------------------- ### Async Initialization and Disposal Example Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Demonstrates asynchronous initialization and disposal using IRequiresAsyncInitialization and IAsyncDisposable. This pattern is useful for loading data or setting up resources asynchronously during dependency resolution. ```csharp using StrongInject; using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; public interface IDb { Task> GetUserPasswordsAsync(); } public class PasswordChecker : IRequiresAsyncInitialization, IAsyncDisposable { private readonly IDb _db; private Dictionary _userPasswords; private Timer _timer; public PasswordChecker(IDb db) { _db = db; } public async ValueTask InitializeAsync() { _userPasswords = await _db.GetUserPasswordsAsync(); _timer = new Timer(async _ => { _userPasswords = await _db.GetUserPasswordsAsync(); }, null, 60000, 60000); } public bool CheckPassword(string user, string password) => _userPasswords.TryGetValue(user, out var correctPassword) && password == correctPassword; public ValueTask DisposeAsync() { return _timer.DisposeAsync(); } } [Register(typeof(PasswordChecker), Scope.SingleInstance)] public partial class Container : IAsyncContainer { private readonly IDb _db; public Container(IDb db) { _db = db; } [Factory] IDb GetDb() => _db; } public static class Program { public static async Task Main(string[] args) { await new Container(new Db()).RunAsync(x => Console.WriteLine(x.CheckPassword(args[0], args[1]) ? "Password is valid" : "Password is invalid")); } } ``` -------------------------------- ### Runtime Configuration with Factory Methods Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Utilize factory methods to conditionally provide instances based on runtime parameters. This example uses a boolean flag to choose between registering `A` or `B`. ```csharp using StrongInject; public interface IInterface { } public class A : IInterface { } public class B : IInterface { } [Register(typeof(A))] [Register(typeof(B))] public partial class Container : IContainer { private readonly bool _useB; public Container(bool useB) => _useB = useB; [Factory] IInterface GetInterfaceInstance(Func a, Func b) => _useB ? b() : a(); } ``` -------------------------------- ### Implementing IFactory for State and Disposal Control Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Use the `IFactory` interface to manage state and disposal within the factory. This example uses `ArrayPool` for efficient array management. ```csharp using StrongInject; using System.Buffers; public interface IInterface {} public class A : IInterface {} public class B : IInterface {} public record InterfaceArrayFactory(A A, B B) : IFactory { public IInterface[] Create() { var array = ArrayPool.Shared.Rent(2); array[0] = A; array[1] = B; return array; } public void Release(IInterface[] instance) { ArrayPool.Shared.Return(instance); } } [Register(typeof(A))] [Register(typeof(B))] [RegisterFactory(typeof(InterfaceArrayFactory))] public partial class Container : IContainer { } ``` -------------------------------- ### Registering a Factory Method in a Container Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Use the `[Factory]` attribute on a method within the container to create complex types. This example shows creating an array of interfaces. ```csharp using StrongInject; public interface IInterface {} public class A : IInterface {} public class B : IInterface {} [Register(typeof(A))] [Register(typeof(B))] public partial class Container : IContainer { [Factory] private IInterface[] CreateInterfaceArray(A a, B b) => new IInterface[] { a, b }; } ``` -------------------------------- ### Configuring Factory and Factory Target Scopes Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Independently control the scope of the factory itself and the scope of the target type it creates. This example sets the factory as a single instance but the target as instance per resolution. ```csharp [RegisterFactory(typeof(InterfaceArrayFactory), scope: Scope.SingleInstance, factoryTargetScope: Scope.InstancePerResolution, typeof(IFactory))] ``` -------------------------------- ### Setting Registration Scope Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Specify the scope of a registration using the `Scope` enum as the second parameter. This example sets `A` to `SingleInstance` and `B` to `InstancePerResolution`. ```csharp using StrongInject; public class A {} public interface IB {} public class B : IB {} [Register(typeof(A), Scope.SingleInstance)] [Register(typeof(B), Scope.InstancePerResolution, typeof(IB))] public partial class Container : IContainer, IContainer {} ``` -------------------------------- ### Registering Dependencies with a Container Source: https://github.com/yairhalberstadt/stronginject/wiki/Home Define a container class that inherits from IContainer and uses the [Register] attribute to specify types for dependency injection. This example shows how to register types A and B. ```csharp using StrongInject; [Register(typeof(A))] [Register(typeof(B))] public class MyContainer : IContainer() {} public class A { public A(B b){} } public class B {} ``` -------------------------------- ### Registering Generic Types Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Register generic types using the generic type syntax (`<>` for single generic, `<,>` for multiple). This example registers `A` and `B` as themselves and as an interface. ```csharp using StrongInject; public class A {} public interface IB {} public class B : IB {} [Register(typeof(A<>))] [Register(typeof(B<,>), typeof(IB<,>))] public partial class Container : IContainer>, IContainer> {} ``` -------------------------------- ### Using Func> for Controlled Disposal Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md This example demonstrates injecting a Func> to acquire and release DbContext instances manually. Using Owned ensures the context is not disposed prematurely, and the Func allows for acquiring new instances as needed, preventing issues with overlapping calls. ```csharp using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using StrongInject; using System; using System.Threading.Tasks; [Register(typeof(SomeViewModel))] [Register(typeof(SomeDbContext))] public partial class Container : IContainer { [Factory] public static SqlConnection CreateSqlConnection() { throw new NotImplementedException(); } } public class SomeViewModel { private readonly Func> dbContextFactory; public SomeViewModel(Func> dbContextFactory) { this.dbContextFactory = dbContextFactory; } public async Task SaveAsync(string newName) { // Using Func> instead of Func ensures that the context will not be // disposed while this method is still using it, even if SomeViewModel is released back to the container. // Using Func> instead of Owned gives the ability for SaveAsync to // get a new SomeDbContext instance that is not being used anywhere else, so overlapping calls to SaveAsync // are no problem. using Owned dbContext = dbContextFactory.Invoke(); dbContext.Value.Set().Add(new SomeEntity { Name = newName }); await dbContext.Value.SaveChangesAsync(); } } public class SomeDbContext : DbContext { public SomeDbContext(SqlConnection connection) : base(new DbContextOptionsBuilder().UseSqlServer(connection).Options) { } } public class SomeEntity { public string Name { get; set; } } ``` -------------------------------- ### Registering Instance as Interfaces with Options Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Demonstrates using the 'Options.AsImplementedInterfaces' option with an [Instance] attribute to register the instance as its interfaces or base classes. This allows for more flexible dependency resolution. ```csharp using StrongInject; using System; public class A { public A(IEqualityComparer equalityComparer){} } public class StringEqualityComparerModule { [Instance(Options.AsImplementedInterfaces)] public static StringComparer StringEqualityComparer = StringComparer.CurrentCultureIgnoreCase; } [Register(typeof(A))] [RegisterModule(typeof(StringEqualityComparerModule))] public partial class Container : IContainer { } ``` -------------------------------- ### Registering and Importing Modules Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Demonstrates how to register types within a module and import that module into a container. This allows for creating reusable sets of registrations. ```csharp using StrongInject; public class A {} [Register(typeof(A))] public class Module {} [RegisterModule(typeof(Module))] public partial class Container : IContainer {} ``` -------------------------------- ### Registering Instance Fields and Properties Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Shows how to register a field or property as an instance dependency using the [Instance] attribute. The field/property is accessed for every dependency of its type. ```csharp using StrongInject; using System.Collections.Generic; public class A { public A(Dictionary configuration){} } [Register(typeof(A))] public partial class Container : IContainer { [Instance] Dictionary _configuration; public Container(Dictionary configuration) => _configuration = configuration; } ``` -------------------------------- ### Loading Asset Files with Typeface Source: https://github.com/yairhalberstadt/stronginject/blob/main/Samples/Xamarin/StrongInject.Samples.XamarinApp.Android/Assets/AboutAssets.txt Shows how to use Typeface.CreateFromAsset to load a font file directly from the application's assets directory. ```C# Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); ``` -------------------------------- ### Handling Optional Parameters with Default Values Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Demonstrates how to provide a default implementation for an interface when it's not explicitly registered. The `?` makes the parameter optional, and a default value is provided. ```csharp public class DefaultImplementation : IInterface {} public interface IInterface {} [Register(typeof(DefaultImplementation))] public class Module { [Decorator] GetIInterface(IInterface? impl = null, DefaultImplementation defaultImpl) => impl ?? defaultImpl; } ``` -------------------------------- ### Exporting Static Instance as Module Registration Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Illustrates registering a static instance field as a module registration. This instance can be accessed as a dependency and is suitable for export if public and static. ```csharp using StrongInject; using System; public class A { public A(IEqualityComparer equalityComparer){} } public class StringEqualityComparerModule { [Instance] public static IEqualityComparer StringEqualityComparer = StringComparer.CurrentCultureIgnoreCase; } [Register(typeof(A))] [RegisterModule(typeof(StringEqualityComparerModule))] public partial class Container : IContainer { } ``` -------------------------------- ### Using Container.Resolve for Manual Disposal Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Use the `Resolve` method to get a disposable wrapper (`Owned`) around a resolved type. You must manually call `Dispose` on the `Owned` object to ensure dependencies are cleaned up. ```csharp using StrongInject; public class Program { public static void Main() { using var ownedOfA = new Container().Resolve(); var a = ownedOfA.Value; System.Console.WriteLine(a.ToString()); } } ``` -------------------------------- ### Declare a Basic Container for a Single Service Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Create a container by declaring a partial class that implements IContainer. StrongInject generates the implementation if the type is resolvable. ```csharp using StrongInject; public class A {} [Register(typeof(A))] public partial class Container : IContainer {} ``` -------------------------------- ### Resolving Array of Registered Types Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Demonstrates how StrongInject automatically resolves an array of registered types when an array type is requested. This example shows distinct registrations for different types implementing a common interface. ```csharp public class A : IInterface {} public class B : IInterface {} public interface IInterface {} [Register(typeof(A), typeof(IInterface))] [Register(typeof(B), typeof(IInterface))] public class Container : IContainer ``` -------------------------------- ### Using Container.Run for Automatic Disposal Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Use the `Run` method to resolve a type, execute a function with it, and automatically dispose of its dependencies. This is suitable when you want to ensure all resolved dependencies are disposed of after use. ```csharp using StrongInject; public class Program { public static void Main() { System.Console.WriteLine(new Container().Run(x => x.ToString())); } } ``` -------------------------------- ### Using a Decorator Factory Method Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md This snippet demonstrates how to use a decorator factory method with the `DecoratorFactory` attribute. This allows for more control over the creation and wrapping of decorated services. ```csharp [Register(typeof(Service), typeof(IService))] public class Container : IContainer { [DecoratorFactory] IService CreateDecorator(IService service) => new ServiceTimingDecorator(service); } ``` -------------------------------- ### Accessing Raw Assets in Xamarin.Android Source: https://github.com/yairhalberstadt/stronginject/blob/main/Samples/Xamarin/StrongInject.Samples.XamarinApp.Android/Assets/AboutAssets.txt Demonstrates how to open and read a raw asset file from the application's Assets directory using the AssetManager in a Xamarin.Android Activity. ```C# public class ReadAsset : Activity { protected override void OnCreate (Bundle bundle) { base.OnCreate (bundle); InputStream input = Assets.Open ("my_asset.txt"); } } ``` -------------------------------- ### Run Container with Action Delegate Source: https://github.com/yairhalberstadt/stronginject/wiki/Containers Use Run to resolve a type and execute an action with it. Dependencies are automatically disposed after the delegate completes. Ensure the resolved type and its dependencies do not escape the delegate's scope. ```csharp using StrongInject; [Register(typeof(A))] public partial class MyContainer : IContainer {} public class A : IDisposable { public void Dispose() { } } var myContainer = new MyContainer(); myContainer.Run(a => Console.WriteLine($"We've resolved an instance of A: {a.ToString()}!!")); ``` -------------------------------- ### Registering a Factory Method from a Module Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Define a static factory method in a separate module class and register the module with the container using `[RegisterModule]`. This allows for better organization of factory logic. ```csharp using StrongInject; public interface IInterface {} public class A : IInterface {} public class B : IInterface {} public class Module { [Factory] public static IInterface[] CreateInterfaceArray(A a, B b) => new IInterface[] { a, b }; } [Register(typeof(A))] [Register(typeof(B))] [RegisterModule(typeof(Module))] public partial class Container : IContainer { } ``` -------------------------------- ### Run Container and Return Value Source: https://github.com/yairhalberstadt/stronginject/wiki/Containers Use Run to resolve a type, execute a function with it, and return a result. Dependencies are automatically disposed after the function completes. Ensure the resolved type and its dependencies do not escape the function's scope. ```csharp using StrongInject; [Register(typeof(A))] public partial class MyContainer : IContainer { } public class A : IDisposable { public void Dispose() { } } var myContainer = new MyContainer(); var aString = myContainer.Run(a => a.ToString()); Console.WriteLine($"We've resolved an instance of A: {aString}!!"); ``` -------------------------------- ### Integrating with Autofac using IFactory Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Integrate with Autofac by creating a custom `IFactory` that resolves and manages instances from an Autofac container. This allows StrongInject to leverage Autofac's resolution and disposal mechanisms. ```csharp using StrongInject; public class A { public A(B b){} } public class B {} public class AutofacFactory(Autofac.IContainer autofacContainer) : IFactory where T : class { private readonly ConcurrentDictionary> _ownedDic = new(); private readonly Autofac.IContainer _autofacContainer; public AutofacFactory(Autofac.IContainer autofacContainer) => _autofacContainer = autofacContainer; public T Create() { var owned = _autofacContainer.Resolve>(); _ownedDic[owned.Value] = owned; return owned.Value; }; public void Release(T instance) { if (_ownedDic.TryGetValue(instance, out var owned)) owned.Dispose(); } } [Register(typeof(A))] public partial class Container : IContainer { [Instance(Options.AsImplementedInterfacesAndUseAsFactory)] private readonly AutofacFactory _autofacFactory; public Container(AutofacFactory autofacFactory) => _autofacFactory = autofacFactory; } ``` -------------------------------- ### Declare Container for Multiple Top-Level Services Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Implement IContainer for multiple types on a single container class. This allows resolving different top-level services while sharing SingleInstance dependencies. ```csharp using StrongInject; public class A {} public class B {} [Register(typeof(A))] [Register(typeof(B))] public partial class Container : IContainer, IContainer {} ``` -------------------------------- ### Resolve Delegate for New Instance Creation Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Use this when you need a new instance of the return type on every delegate call. The delegate parameters can be used in the resolution and will override existing resolutions. ```csharp using System; using StrongInject; public class A { public A(Func fB) => Console.WriteLine(fB() != fB()); //prints true } public class B{} [Register(typeof(A))] [Register(typeof(B))] public class Container : IContainer {} ``` -------------------------------- ### Generic Decorator Factory with Dynamic Proxies Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md This advanced snippet shows a generic decorator factory method used with `Castle.DynamicProxy` to intercept and time all method calls on services. This is useful for cross-cutting concerns like logging or performance monitoring. ```csharp using Castle.DynamicProxy; using StrongInject; using System; using System.Diagnostics; using System.Threading; public class Interceptor : IInterceptor { public void Intercept(IInvocation invocation) { var stopwatch = Stopwatch.StartNew(); invocation.Proceed(); stopwatch.Stop(); Console.WriteLine($"Call to {invocation.Method.Name} took {stopwatch.ElapsedMilliseconds} ms"); } } public class Foo { } public class Bar { } public interface IService1 { void Frob(); Foo GetFoo(); } public interface IService2 { Bar UseBar(Bar bar); } public class Service1 : IService1 { public void Frob() { Thread.Sleep(10); } public Foo GetFoo() { Thread.Sleep(20); return new Foo(); } } public class Service2 : IService2 { public Bar UseBar(Bar bar) { Thread.Sleep(30); return bar; } } [Register(typeof(Service1), typeof(IService1))] [Register(typeof(Service2), typeof(IService2))] public partial class Container : IContainer, IContainer { private readonly IInterceptor _interceptor = new Interceptor(); private readonly ProxyGenerator _proxyGenerator = new ProxyGenerator(); [DecoratorFactory] T Time(T t) where T : class { if (typeof(T).IsInterface) { return _proxyGenerator.CreateInterfaceProxyWithTarget(t, _interceptor); } else { return _proxyGenerator.CreateClassProxyWithTarget(t, _interceptor); } } } public class Program { public static void Main() { var container = new Container(); container.Run(x => { x.Frob(); _ = x.GetFoo(); }); container.Run(x => _ = x.UseBar(new Bar())); } } ``` -------------------------------- ### Declare Container for a Single Top-Level Service Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Define a container for a single top-level service. StrongInject checks for all necessary registrations at compile time. ```csharp using StrongInject; public class MyService {} public class MyApp { public MyApp(MyService myService) {} } [Register(typeof(MyApp))] public partial class MyContainer : IContainer {} ``` -------------------------------- ### Array Resolution with Single Instance Scope Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Shows how StrongInject treats a single instance registration differently when resolving an array. A type registered with Scope.SingleInstance will still be included in the array, even if other registrations for the same type exist. ```csharp public class A : IInterface {} public interface IInterface {} [Register(typeof(A), typeof(IInterface))] [Register(typeof(A), Scope.SingleInstance, typeof(IInterface))] public class Container : IContainer ``` -------------------------------- ### Registering a Service Decorator Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md This snippet shows how to register a decorator for a service using the `RegisterDecorator` attribute. The decorator wraps an existing service implementation to add custom behavior, such as timing. ```csharp using System; using System.Diagnostics; using StrongInject; public class Foo {} public interface IService { Foo GetFoo() } public class Service : IService { public Foo GetFoo() => new Foo(); } public class ServiceTimingDecorator : IService { private readonly IService _impl; public ServiceTimingDecorator(IService impl) => _impl = impl; public Foo GetFoo() { var watch = Stopwatch.StartNew(); var foo = _impl.GetFoo(); watch.Stop; Console.WriteLine($"Getting foo took {watch.ElapsedMilliseconds} ms"); return foo; } } [Register(typeof(Service), typeof(IService))] [RegisterDecorator(typeof(ServiceTimingDecorator), typeof(IService))] public class Container : IContainer {} ``` -------------------------------- ### Using the Container to Resolve a Type Source: https://github.com/yairhalberstadt/stronginject/wiki/Home Instantiate the custom container and use its Run method to resolve an instance of a registered type (e.g., type A). The resolved instance is then used within the provided lambda expression. ```csharp var myContainer = new MyContainer(); myContainer.Run(a => Console.WriteLine($"We've resolved an instance of A: {a.ToString()}!!")); ``` -------------------------------- ### Resolve Delegate with Parameters Source: https://github.com/yairhalberstadt/stronginject/blob/main/README.md Use this to provide parameters to the resolved type that are not available at resolution time. The delegate parameters can be used in the resolution and will override existing resolutions. ```csharp using System; using StrongInject; public class Server { private Handler _frobbingHandler; private Handler _nonFrobbingHandler; public Server(Func handlerFunc) => (_frobbingHandler, _nonFrobbingHandler) = (handlerFunc(true), handlerFunc(false)); public bool HandleRequest(Request request, bool shouldFrob) => shouldFrob ? _frobbingHandler.HandleRequest(request) : _nonFrobbingHandler.HandleRequest(request); } public class Handler { public Handler(bool shouldFrob) => ... } [Register(typeof(Server))] [Register(typeof(Handler))] public class Container : IContainer {} ```