Autofac是一款IOC框架,比較於其餘的IOC框架,如spring.NET,Unity,Castle等等所包含的,它很輕量級性能上也是很高的。因而,今天抽空研究了下它。下載地址:http://code.google.com/p/autofac/downloads/listjava
1)解壓它的壓縮包,主要看到Autofac.dll,Autofac.Configuration.dll,這也是本篇文章重點使用的Autofac的類庫。mysql
2)建立一個控制檯工程,而且引用以上的DLL文件。建立一個數據庫操做接口IDatabase.cs:spring
/// <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四種操做的方法。sql
3)建立兩種數據庫的操做類,SqlDatabase.cs以及OracleDatabase.cs:docker
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)接着建立一個數據庫管理器DatabaseManager.cs:oracle
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)在控制檯中,編寫如下測試程序:框架
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");
}
運行結果:函數
![image image](http://static.javashuo.com/static/loading.gif)
分析:sqlserver
這裏經過ContainerBuilder方法RegisterType對DatabaseManager進行註冊,當註冊的類型在相應獲得的容器中能夠Resolve你的DatabaseManager實例。
builder.RegisterType<SqlDatabase>().As<IDatabase>();經過AS可讓DatabaseManager類中經過構造函數依賴注入類型相應的接口。
Build()方法生成一個對應的Container實例,這樣,就能夠經過Resolve解析到註冊的類型實例。
一樣地,若是你修改數據庫類型註冊爲:
builder.RegisterType<OracleDatabase>().As<IDatabase>();
運行結果:
![image image](http://static.javashuo.com/static/loading.gif)
6)顯然以上的程序中,SqlDatabase或者OracleDatabase已經暴露於客戶程序中了,如今我想將該類型選擇經過文件配置進行讀取。Autofac自帶了一個Autofac.Configuration.dll 很是方便地對類型進行配置,避免了程序的從新編譯。
修改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配置節點對組件進行處理。
對應的客戶端程序改成:
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");
}
運行結果:
![image image](http://static.javashuo.com/static/loading.gif)
7)另外還有一種方式,經過Register方法進行註冊:
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");
}
獲得結果也是同樣的。
8)如今我想經過一個用戶類來控制操做權限,好比增刪改的權限,建立一個用戶類:
/// <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);
}
}
在構造函數中增長了一個參數User,而Add,Save,Remove增長了權限判斷。
修改客戶端程序:
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 ...");
}
運行結果:
分析:
builder.RegisterInstance(user).As<User>();註冊User實例。
builder.Register(c => new DatabaseManager(c.Resolve<IDatabase>(), c.Resolve<User>()));經過Lampda表達式註冊DatabaseManager實例。
若是這裏我修改User的屬性值:
User user = new User { Id = 2, Name = "zhangsan" };
運行結果:
![image image](http://static.javashuo.com/static/loading.gif)
說明該用戶無權限操做。
源代碼下載:AutofacDemo.rar
郵箱:sunleepy(AT)gmail.com
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文連接,不然保留追究法律責任的權利。