# Nkit.Proj.Tmpl **Repository Path**: robinkits/Nkit.Proj.Tmpl ## Basic Information - **Project Name**: Nkit.Proj.Tmpl - **Description**: 初始化的工程结构 - **Primary Language**: C# - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-03-13 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README Nkit.IocManager [![Build status](https://ci.appveyor.com/api/projects/status/20cb4av2n7114u80?svg=true)](https://ci.appveyor.com/project/IRobinjiang/nkit-autofac) ===================== |Package|Status|Supported Platforms| |:-:|:-:|:-:| |Nkit.IocManager| [![NuGet version](https://badge.fury.io/nu/Nkit.IocManager.svg)](https://badge.fury.io/nu/Nkit.IocManager)| .NET Standard 2.0| |Nkit.DynamicProxy|[![NuGet version](https://badge.fury.io/nu/Nkit.DynamicProxy.svg)](https://badge.fury.io/nu/Nkit.DynamicProxy)|.NET Standard 2.0| Nkit.IocManager allows Autofac Container to be portable. It also provides entire resolve methods which belong to Autofac Container and also provides conventional registration mechanism. IocManager is the best alternative to [common Service Locator anti-pattern](http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/). ## Extension Oriented Registrations Extension sample: ```csharp public static class StoveRegistrationExtensions { public static IIocBuilder UseStove(this IIocBuilder builder) { RegisterDefaults(builder); return builder; } private static void RegisterDefaults(IIocBuilder builder) { builder.RegisterServices(r => r.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly())); builder.RegisterServices(r => r.Register(context => SequentialGuidGenerator.Instance)); builder.RegisterServices(r => r.Register(Lifetime.Singleton)); } public static IIocBuilder UseDefaultConnectionStringResolver(this IIocBuilder builder) { builder.RegisterServices(r => r.Register()); return builder; } public static IIocBuilder UseDefaultEventBus(this IIocBuilder builder) { builder.RegisterServices(r => r.Register(context => EventBus.Default)); return builder; } public static IIocBuilder UseEventBus(this IIocBuilder builder) { builder.RegisterServices(r => r.Register()); return builder; } } ``` ## Registrations ### Conventional assembly registrations There are 3 interfaces to mark an implementation. * `ITransientDependency` : Marks implementation as PerDepedency * `ISingletonDependency` : Marks implementation as SingleInstance * `ILifetimeScopeDependency` : Marks implementation as LifetimeScope Interface and classes: ```csharp interface ISimpleDependency1 {} class SimpleDependency1 : ISimpleDependency1, ITransientDependency {} interface ISimpleDependency2 {} class SimpleDependency2 : ISimpleDependency2, ISingletonDependency {} interface ISimpleDependency3 {} class SimpleDependency3 : ISimpleDependency3, ILifetimeScopeDependency {} ``` To detect and register all marked implementations with it's *DefaultInterface* : ``` private static void RegisterSomeFeature(IIocBuilder builder) { builder.RegisterServices(r => r.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly())); } ``` With this feature, you no longer don't have to define your registrations in `Builder`'s `Load` method explicitly. `RegisterAssemblyByConvention` does this with [interface marking pattern](https://en.wikipedia.org/wiki/Marker_interface_pattern). ## IocManager Using After the container build which means `CreateResolver()` it can use: ```csharp IocManager.Instance.Resolve(); ``` This using is service locator approach, but it provides some extensions to avoid memory leaks. Resolve instance: ```csharp IocManager.Instance.Resolve(); ``` Disposable resolve to avoid memory leaks: ```csharp SimpleDisposableDependency simpleDisposableDependency; using (var simpleDependencyWrapper = IocManager.Instance.ResolveAsDisposable()) { simpleDisposableDependency = simpleDependencyWrapper.Object; } simpleDisposableDependency.DisposeCount.Should().Be(1); ``` Scoped resolver to avoid memory leaks: ```csharp SimpleDisposableDependency simpleDisposableDependency; using (IIocScopedResolver iocScopedResolver = IocManager.Instance.CreateScope()) { simpleDisposableDependency = iocScopedResolver.Resolve(); } simpleDisposableDependency.DisposeCount.Should().Be(1); ``` ## Resolvings ### Injectable Resolvers * `IResolver`: Atomic resolver which uses Autofac's `IComponentContext` internally. * `IScopeResolver` : Able to start a new lifetime scope. An abstraction to Autofac's `ILifetimeScope` ---- ## Property Injection Nkit.IocManager also provides property injection on public and private properties with `InjectPropertiesAsAutowired()` extension. It does this autowire operation internally. Just use register api `builder.RegisterServices(r => r.Register());` it autowires all propery injections implicitly according to your `[DoNotInject]` attribute. ```csharp builder.RegisterType().AsSelf().AsImplementedInterfaces().InjectPropertiesAsAutowired(); ``` Also you may not want to inject all properties for a dependency, it can be done with putting single attribute to target property. `DoNotInjectAttribute` ```csharp class MySimpleClass : IMySimpleClass, ILifeTimeScopeDependency { [DoNotInject] public IHuman Human { get; set; } } ``` ## Injectable IocManager IocManager also self-injectable in any dependencies. For example: ```csharp class SimpleDependencyWithIocManager { private readonly IIocManager _iocManager; public SimpleDependencyWithIocManager(IIocManager iocManager) { _iocManager = iocManager; } public IIocManager GetIocManager() { return _iocManager; } public void DoSomeStuff() { _iocManager.Resolve(); // It would be disposed automatically. using (var someType = _iocManager.ResolveAsDisposable()) { someType.Object.DoStuff(); } // All instances would be disposed automatically after the using statement. using (IIocScopedResolver iocScopedResolver = _iocManager.CreateScope()) { iocScopedResolver.Resolve(); iocScopedResolver.Resolve(); iocScopedResolver.Resolve(); } } } ``` feel free to use `IIocManager` for resolving operations in any dependency. # Example Extension: ```csharp public static class SomeRegistrationExtensions { public static IIocBuilder UseSomeFeature(this IIocBuilder builder) { builder.RegisterServices(r => r.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly())); //do some registrations which belong to the feature //... return builder; } } ``` Composition Root or Program.cs ```csharp internal class Program { private static void Main(string[] args) { IocBuilder.New .UseAutofacContainerBuilder() .UseSomeFeature(); } } ```