文章出處

快到年終了, 最近項目比較悠閑, 就想總結下, 項目中所使用到的一些技術, 以及使用方法.

之前有寫過Dapper以及Dapper的一個擴展, 這些也是項目中使用過的. 算是一個溫故而知新吧.

代碼:

public interface IAnimal
{
 void Say();
}

public class Dog : IAnimal
{
 public string Name { get; set; }
 public void Say()
 {
 Console.WriteLine("汪汪汪!");
 if (!string.IsNullOrEmpty(Name))
 {
 Console.WriteLine("此汪名叫 " + Name);
 }
 }
}

public class Cat : IAnimal
{
 public string Name { get; set; }
 public void Say()
 {
 Console.WriteLine("喵喵喵!");
 if (!string.IsNullOrEmpty(Name))
 {
 Console.WriteLine("此喵名叫 " + Name);
 }
 }
}

public class Person
{
 IAnimal adopt;

 public Person() { }

 public void Self()
 {
 Console.WriteLine("我是主人");
 }

 public Person(IAnimal MyPerson)
 {
 adopt = MyPerson;
 }

 public void Say()
 {
 Console.WriteLine("我領養了一只小動物");
 adopt.Say();
 }
}

 

 一、類型注冊

類型的注冊, 使用的方法是container.Resolve<Type>()和container.Resolve(typeof(Type))兩個方法.

示例:

var builder = new ContainerBuilder();

builder.RegisterType<Person>();
builder.RegisterType<Dog>().As<IAnimal>();
builder.RegisterType(typeof(Cat));

var container = builder.Build();

var person = container.Resolve<Person>();
person.Self();
Console.WriteLine("---------");
var animal = container.Resolve<IAnimal>();
animal.Say();
Console.WriteLine("---------");
var cat = container.Resolve<Cat>();
cat.Say();

從圖上可以看出, 通過這種方式注冊類型之后, 可以正常獲取到實例

 

二、實例注冊

示例: (共同部分我就不貼了, 只貼主要部分)

builder.RegisterInstance(new Person(new Dog()));

//-------------------------------------------------
var person = container.Resolve<Person>();
person.Self();
person.Say();

這里還有一種為單例模式準備的實現, 可以把單例托管為容器單例, 我這里就沒有寫那么多了, 直接上了一個非單例的示例. 也是有效果的喲

builder.RegisterInstance(new Cat()).ExternallyOwned();

//-------------------------------------------------
var cat = container.Resolve<Cat>();
cat.Name = "miao";
cat.Say();

var cat1 = container.Resolve<Cat>();
cat1.Say();

這里我后來試了一下, 就算不加那個, 得到的效果也是單例的效果 

 

 三、Lambda方式注冊 

//builder.RegisterType<Dog>().As<IAnimal>();
builder.Register(c => new Person(c.Resolve<IAnimal>()));
builder.RegisterType<Dog>().As<IAnimal>();

//-------------------------------------------------
var person = container.Resolve<Person>();
person.Say();

IAnimal注冊的位置不受限制, 在前面, 在后面, 都是不受影響的, 但是不能沒有啊, 沒有就會報錯了, 程序找不到.

 

四、程序集注冊

這種方式適合懶人用

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces();

//-------------------------------------------------
var animal = container.Resolve<IAnimal>();
animal.Say();

我這里面有兩個類實現了IAnimal接口, 但是為什么這里獲取到的是cat類, 而不是dog類呢?

 

五、泛型注冊

builder.RegisterGeneric(typeof(List<>)).As(typeof(IList<>)).InstancePerLifetimeScope();
var container = builder.Build();
//-------------------------------------------------
IList<Dog> dogs = container.Resolve<IList<Dog>>();

這里獲取到的dogs是一個空的集合, 并不是null值.

 

六、默認注冊

如果一個類, 被多次注冊, 會以最后一次注冊為準, 就想上面 "四" 出現的情況, 只輸出了"喵喵喵", 那是因為Dog類先注冊, Cat類后注冊, 把之前的覆蓋掉了. 注意, 覆蓋并不是沒有了, 只是不能通過這種方式獲取了而已, 還是可以通過別的方式來獲取你想要的類的.

先看一下效果:

builder.RegisterType<Dog>().As<IAnimal>();
builder.RegisterType<Cat>().As<IAnimal>();

//-------------------------------------------------
var animal = container.Resolve<IAnimal>();
animal.Say();

如果我想要輸出Dog類咋搞呢. 使用 PreserveExistingDefaults(), 這個方法是告訴容器, 這次注冊的不是默認輸出的.

builder.RegisterType<Dog>().As<IAnimal>();
builder.RegisterType<Cat>().As<IAnimal>().PreserveExistingDefaults();
//-------------------------------------------------
var animal = container.Resolve<IAnimal>();
animal.Say();

 那如果想一個接口上注冊多個類, 并且都能正常獲取呢? 那就看下一篇分解了

 參考資料:

Autofac 組件、服務、自動裝配 《第二篇》

Autofac文檔


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


文章標籤
全站熱搜
創作者介紹
創作者 大師兄 的頭像
大師兄

IT工程師數位筆記本

大師兄 發表在 痞客邦 留言(0) 人氣(0)