Autofac简单教程
<h3>1. 普通使用方式</h3>
<p>使用Register标签自动注册,直接resolve接口获得对象实例,注意Singleton=true或者false的区别</p>
<pre><code class="language-csharp">namespace ConsoleApp1
{
interface IHelloWorld
{
void SayHello();
}
///注意!!Singleton=true代表是单例,每次resolve接口都会返回相同的对象实例
///注意!!Singleton=false代表非单例,每次resolve接口都会返回不同的对象实例
[Register(Singleton =false)]
class TestHello : IHelloWorld
{
public void SayHello()
{
Console.WriteLine("{0}-{1}", this.GetHashCode(), "TestHello");
}
}
class Program
{
static void Main(string[] args)
{
///初始化,扫描Register属性,自动注册接口
DependencyInjection.Init();
var instance1 = DependencyInjection.Container.Resolve<IHelloWorld>();
instance1.SayHello();
var instance2 = DependencyInjection.Container.Resolve<IHelloWorld>();
instance2.SayHello();
}
}
}</code></pre>
<p>输出:</p>
<pre><code class="language-csharp">//Singleton=false时输出:
63208015-TestHello
32001227-TestHello
//Singleton=true时输出:
63208015-TestHello
63208015-TestHello</code></pre>
<h3>2.进阶使用方式</h3>
<p>按照Key来注册,并按照key来Resolve接口
<strong>适合用来做不同端的业务逻辑实现的区分</strong></p>
<pre><code class="language-csharp">namespace ConsoleApp1
{
interface IHelloWorld
{
void SayHello();
}
///注意!!指定了Key=“3D”
[Register(As =typeof(IHelloWorld), Key ="3D")]
class Hello3D : IHelloWorld
{
public void SayHello()
{
Console.WriteLine("{0}-{1}", this.GetHashCode(), "Hello3D");
}
}
///注意!!指定了Key=“VR”
[Register(As = typeof(IHelloWorld), Key = "VR")]
class HelloVR : IHelloWorld
{
public void SayHello()
{
Console.WriteLine("{0}-{1}", this.GetHashCode(), "HelloVR");
}
}
class Program
{
static void Main(string[] args)
{
DependencyInjection.Init();
//按照Key【3D】来Resolve接口
var instance3D = DependencyInjection.Container.ResolveKeyed<IHelloWorld>("3D");
instance3D.SayHello();
//按照Key【VR】来Resolve接口
var instanceVR = DependencyInjection.Container.ResolveKeyed<IHelloWorld>("VR");
instanceVR.SayHello();
///默认Resolve方式,依然取到的是最后注册类的实例
var c = DependencyInjection.Container.Resolve<IHelloWorld>();
c.SayHello();
}
}
}</code></pre>
<p>输出:</p>
<pre><code class="language-csharp">32001227-Hello3D //DependencyInjection.Container.ResolveKeyed<IHelloWorld>("3D")
19575591-HelloVR
41962596-HelloVR</code></pre>
<h3>3.运行时替换</h3>
<p>在运行时,依然可以替换接口的实现,主要用到AutofacHelper.Update<T>这个方法</p>
<pre><code class="language-csharp">namespace ConsoleApp1
{
...
class OverrideHello : IHelloWorld
{
public void SayHello()
{
Console.WriteLine("{0}-{1}", this.GetHashCode(), "OverrideHello");
}
}
class Program
{
static void Main(string[] args)
{
DependencyInjection.Init();
var testHello = DependencyInjection.Container.Resolve<IHelloWorld>();
testHello.SayHello();
OverrideHello overrideInstance = new OverrideHello();
AutofacHelper.Update<IHelloWorld>(overrideInstance);
var d = DependencyInjection.Container.Resolve<IHelloWorld>();
d.SayHello()
}
}
}</code></pre>
<p>输出:</p>
<pre><code class="language-csharp">63208015-TestHello
32001227-OverrideHello</code></pre>
<h3>4.如何提前做初始化</h3>
<p>有时候某些接口的实现,涉及较复杂的初始化操作,比如读取大量的文件,如果在使用时再初始化,会带来比较明显的卡顿,可以考虑使用autofac自带的IStartable接口,它会在DependencyInjection.Init()的过程中被调用
可以在这个接口中触发异步初始化的功能。</p>
<pre><code class="language-csharp">namespace ConsoleApp1
{
...
[Register(Singleton = true)]
class Start : IStartable
{
void IStartable.Start()
{
Console.WriteLine("IStartable.Start");
}
}
class Program
{
static void Main(string[] args)
{
DependencyInjection.Init();
var testHello = DependencyInjection.Container.Resolve<IHelloWorld>();
testHello.SayHello();
}
}
}</code></pre>
<p>输出:</p>
<pre><code class="language-csharp">IStartable.Start
32001227-TestHello</code></pre>