8000 GitHub - robinkits/Nkit.Proj.Tmpl: 初始化的工程结构
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

robinkits/Nkit.Proj.Tmpl

Repository files navigation

Nkit.IocManager Build status

Package Status Supported Platforms
Nkit.IocManager NuGet version .NET Standard 2.0
Nkit.DynamicProxy NuGet version .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.

Extension Oriented Registrations

Extension sample:

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<IGuidGenerator>(context => SequentialGuidGenerator.Instance));
       builder.RegisterServices(r => r.Register<IStoveStartupConfiguration, StoveStartupConfiguration>(Lifetime.Singleton));
   }

   public static IIocBuilder UseDefaultConnectionStringResolver(this IIocBuilder builder)
   {
       builder.RegisterServices(r => r.Register<IConnectionStringResolver, DefaultConnectionStringResolver>());
       return builder;
   }

   public static IIocBuilder UseDefaultEventBus(this IIocBuilder builder)
   {
       builder.RegisterServices(r => r.Register<IEventBus>(context => EventBus.Default));
       return builder;
   }

   public static IIocBuilder UseEventBus(this IIocBuilder builder)
   {
       builder.RegisterServices(r => r.Register<IEventBus, EventBus>());
       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:

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.

IocManager Using

After the container build which means CreateResolver() it can use:

IocManager.Instance.Resolve<ISimpleDependency3>();

This using is service locator approach, but it provides some extensions to avoid memory leaks.

Resolve instance:

IocManager.Instance.Resolve<IMyTransientClass>();

Disposable resolve to avoid memory leaks:

SimpleDisposableDependency simpleDisposableDependency;
using (var simpleDependencyWrapper = IocManager.Instance.ResolveAsDisposable<SimpleDisposableDependency>())
{
   simpleDisposableDependency = simpleDependencyWrapper.Object;
}

simpleDisposableDependency.DisposeCount.Should().Be(1);

Scoped resolver to avoid memory leaks:

SimpleDisposableDependency simpleDisposableDependency;
using (IIocScopedResolver iocScopedResolver = IocManager.Instance.CreateScope())
{
    simpleDisposableDependency = iocScopedResolver.Resolve<SimpleDisposableDependency>();
}

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<IConnectionStringResolver, DefaultConnectionStringResolver>()); it autowires all propery injections implicitly according to your [DoNotInject] attribute.

builder.RegisterType<ISimpleDependency>().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

 class MySimpleClass : IMySimpleClass, ILifeTimeScopeDependency
 {
     [DoNotInject]
     public IHuman Human { get; set; }
 }

Injectable IocManager

IocManager also self-injectable in any dependencies. For example:

class SimpleDependencyWithIocManager
{
    private readonly IIocManager _iocManager;

    public SimpleDependencyWithIocManager(IIocManager iocManager)
    {
        _iocManager = iocManager;
    }

    public IIocManager GetIocManager()
    {
        return _iocManager;
    }

    public void DoSomeStuff()
    {
        _iocManager.Resolve<SomeType>();

        // It would be disposed automatically.
        using (var someType = _iocManager.ResolveAsDisposable<SomeType>())
        {
            someType.Object.DoStuff();
        }

        // All instances would be disposed automatically after the using statement.
        using (IIocScopedResolver iocScopedResolver = _iocManager.CreateScope())
        {
            iocScopedResolver.Resolve<SomeKindOfType>();
            iocScopedResolver.Resolve<HumanClass>();
            iocScopedResolver.Resolve<BirdClass>();
        }
    }
}

feel free to use IIocManager for resolving operations in any dependency.

Example

Extension:

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

internal class Program
{
    private static void Main(string[] args)
    {
        IocBuilder.New
                  .UseAutofacContainerBuilder()
                  .UseSomeFeature();
    }
}

About

初始化的工程结构

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published
0