淺析依賴注入框架Autofac的使用
下面通過代碼給大家分享下依賴注入框架Autofac的使用,具體如下所示:
Autofac是一款I(lǐng)OC框架,比較于其他的IOC框架,如Spring.NET,Unity,Castle等等所包含的,它很輕量級性能上也是很高的。
1)解壓它的壓縮包,主要看到Autofac.dll,Autofac.Configuration.dll,這也是本篇文章重點(diǎn)使用的Autofac的類庫。
2)創(chuàng)建一個(gè)控制臺(tái)工程,并且引用以上的DLL文件。創(chuàng)建一個(gè)數(shù)據(jù)庫操作接口IDatabase.cs:
/// <summary> /// Database operate interface /// </summary> public interface IDatabase { string Name { get; } void Select(string commandText); void Insert(string commandText); void Update(string commandText); void Delete(string commandText); }
這里包含CRUD四種操作的方法。
3)創(chuàng)建兩種數(shù)據(jù)庫的操作類,SqlDatabase.cs以及OracleDatabase.cs:
public class SqlDatabase : IDatabase { public string Name { get { return "sqlserver"; } } public void Select(string commandText) { Console.WriteLine(string.Format("'{0}' is a query sql in {1}!", commandText, Name)); } public void Insert(string commandText) { Console.WriteLine(string.Format("'{0}' is a insert sql in {1}!", commandText, Name)); } public void Update(string commandText) { Console.WriteLine(string.Format("'{0}' is a update sql in {1}!", commandText, Name)); } public void Delete(string commandText) { Console.WriteLine(string.Format("'{0}' is a delete sql in {1}!", commandText, Name)); } }
以及
public class OracleDatabase : IDatabase { public string Name { get { return "oracle"; } } public void Select(string commandText) { Console.WriteLine(string.Format("'{0}' is a query sql in {1}!", commandText, Name)); } public void Insert(string commandText) { Console.WriteLine(string.Format("'{0}' is a insert sql in {1}!", commandText, Name)); } public void Update(string commandText) { Console.WriteLine(string.Format("'{0}' is a update sql in {1}!", commandText, Name)); } public void Delete(string commandText) { Console.WriteLine(string.Format("'{0}' is a delete sql in {1}!", commandText, Name)); } }
4)接著創(chuàng)建一個(gè)數(shù)據(jù)庫管理器DatabaseManager.cs:
public class DatabaseManager { IDatabase _database; public DatabaseManager(IDatabase database) { _database = database; } public void Search(string commandText) { _database.Select(commandText); } public void Add(string commandText) { _database.Insert(commandText); } public void Save(string commandText) { _database.Update(commandText); } public void Remove(string commandText) { _database.Delete(commandText); } }
5)在控制臺(tái)中,編寫以下測試程序:
var builder = new ContainerBuilder();
builder.RegisterType<DatabaseManager>();
builder.RegisterType<SqlDatabase>().As<IDatabase>();
using (var container = builder.Build())
{
var manager = container.Resolve<DatabaseManager>();
manager.Search("SELECT * FORM USER");
}
運(yùn)行結(jié)果:
分析:
這里通過ContainerBuilder方法RegisterType對DatabaseManager進(jìn)行注冊,當(dāng)注冊的類型在相應(yīng)得到的容器中可以Resolve你的DatabaseManager實(shí)例。
builder.RegisterType<SqlDatabase>().As<IDatabase>();
通過AS可以讓DatabaseManager類中通過構(gòu)造函數(shù)依賴注入類型相應(yīng)的接口。
Build()方法生成一個(gè)對應(yīng)的Container實(shí)例,這樣,就可以通過Resolve解析到注冊的類型實(shí)例。
同樣地,如果你修改數(shù)據(jù)庫類型注冊為:
builder.RegisterType<OracleDatabase>().As<IDatabase>();
運(yùn)行結(jié)果:
6)顯然以上的程序中,SqlDatabase或者OracleDatabase已經(jīng)暴露于客戶程序中了,現(xiàn)在我想將該類型選擇通過文件配置進(jìn)行讀取。
Autofac自帶了一個(gè)Autofac.Configuration.dll 非常方便地對類型進(jìn)行配置,避免了程序的重新編譯。
修改App.config:
<configuration>
<configSections>
<section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/>
</configSections>
<autofac defaultAssembly="AutofacDemo">
<components>
<component type="AutofacDemo.SqlDatabase, AutofacDemo" service="AutofacDemo.IDatabase" />
</components>
</autofac>
</configuration>
通過Autofac.Configuration.SectionHandler配置節(jié)點(diǎn)對組件進(jìn)行處理。
對應(yīng)的客戶端程序改為:
var builder = new ContainerBuilder();
builder.RegisterType<DatabaseManager>();
builder.RegisterModule(new ConfigurationSettingsReader("autofac"));
using (var container = builder.Build())
{
var manager = container.Resolve<DatabaseManager>();
manager.Search("SELECT * FORM USER");
}
運(yùn)行結(jié)果:
7)另外還有一種方式,通過Register方法進(jìn)行注冊:
var builder = new ContainerBuilder(); //builder.RegisterType<DatabaseManager>(); builder.RegisterModule(new ConfigurationSettingsReader("autofac")); builder.Register(c => new DatabaseManager(c.Resolve<IDatabase>())); using (var container = builder.Build()) { var manager = container.Resolve<DatabaseManager>(); manager.Search("SELECT * FORM USER"); }
得到結(jié)果也是一樣的。
8)現(xiàn)在我想通過一個(gè)用戶類來控制操作權(quán)限,比如增刪改的權(quán)限,創(chuàng)建一個(gè)用戶類:
/// <summary> /// Id Identity Interface /// </summary> public interface Identity { int Id { get; set; } } public class User : Identity { public int Id { get; set; } public string Name { get; set; } }
修改DatabaseManager.cs代碼:
public class DatabaseManager { IDatabase _database; User _user; public DatabaseManager(IDatabase database) : this(database, null) { } public DatabaseManager(IDatabase database, User user) { _database = database; _user = user; } /// <summary> /// Check Authority /// </summary> /// <returns></returns> public bool IsAuthority() { bool result = _user != null && _user.Id == 1 && _user.Name == "leepy" ? true : false; if (!result) Console.WriteLine("Not authority!"); return result; } public void Search(string commandText) { _database.Select(commandText); } public void Add(string commandText) { if (IsAuthority()) _database.Insert(commandText); } public void Save(string commandText) { if (IsAuthority()) _database.Update(commandText); } public void Remove(string commandText) { if (IsAuthority()) _database.Delete(commandText); } }
在構(gòu)造函數(shù)中增加了一個(gè)參數(shù)User,而Add,Save,Remove增加了權(quán)限判斷。
修改客戶端程序:
User user = new User { Id = 1, Name = "leepy" }; var builder = new ContainerBuilder(); builder.RegisterModule(new ConfigurationSettingsReader("autofac")); builder.RegisterInstance(user).As<User>(); builder.Register(c => new DatabaseManager(c.Resolve<IDatabase>(), c.Resolve<User>())); using (var container = builder.Build()) { var manager = container.Resolve<DatabaseManager>(); manager.Add("INSERT INTO USER ..."); }
運(yùn)行結(jié)果:
分析:
builder.RegisterInstance(user).As<User>();注冊User實(shí)例。
builder.Register(c => new DatabaseManager(c.Resolve<IDatabase>(), c.Resolve<User>()));通過Lampda表達(dá)式注冊
DatabaseManager實(shí)例。
如果這里我修改User的屬性值:
User user = new User { Id = 2, Name = "zhangsan" };
運(yùn)行結(jié)果:
說明該用戶無權(quán)限操作。
以上就是本文的全部內(nèi)容,希望大家喜歡。
相關(guān)文章
Unity調(diào)用手機(jī)攝像機(jī)識別二維碼
這篇文章主要為大家詳細(xì)介紹了Unity調(diào)用手機(jī)攝像機(jī)識別二維碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07C#實(shí)現(xiàn)讀取注冊表監(jiān)控當(dāng)前操作系統(tǒng)已安裝軟件變化的方法
這篇文章主要介紹了C#實(shí)現(xiàn)讀取注冊表監(jiān)控當(dāng)前操作系統(tǒng)已安裝軟件變化的方法,涉及C#針對注冊表的讀取與監(jiān)控技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-08-08C#Process的OutputDataReceived事件不觸發(fā)問題及解決
這篇文章主要介紹了C#Process的OutputDataReceived事件不觸發(fā)問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02C# Dynamic關(guān)鍵字之:解析dynamic就是Object
本篇文章是對C#中dynamic關(guān)鍵字就是Object進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C#中自定義高精度Timer定時(shí)器的實(shí)例教程
這篇文章主要介紹了C#中自定義高精度Timer定時(shí)器的實(shí)例教程,多線程的Timer編寫需要注意線程安全的問題,需要的朋友可以參考下2016-04-04