天天看點

Ioc容器-Autofac 之四-依賴注入架構Autofac的簡單使用

依賴注入架構Autofac的簡單使用

      Autofac是一款IOC架構,比較于其他的IOC架構,如Spring.NET,Unity,Castle等等所包含的,它很輕量級性能上也是很高的。于是,今天抽空研究了下它。下載下傳位址:​​http://code.google.com/p/autofac/downloads/list​​

1)解壓它的壓縮包,主要看到Autofac.dll,Autofac.Configuration.dll,這也是本篇文章重點使用的Autofac的類庫。

2)建立一個控制台工程,并且引用以上的DLL檔案。建立一個資料庫操作接口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)建立兩種資料庫的操作類,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)接着建立一個資料庫管理器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)在控制台中,編寫以下測試程式:

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

"

); 

運作結果:

​​

Ioc容器-Autofac 之四-依賴注入架構Autofac的簡單使用

​​

分析:

這裡通過ContainerBuilder方法RegisterType對DatabaseManager進行注冊,當注冊的類型在相應得到的容器中可以Resolve你的DatabaseManager執行個體。

builder.RegisterType<SqlDatabase>().As<IDatabase>();通過AS可以讓DatabaseManager類中通過構造函數依賴注入類型相應的接口。

Build()方法生成一個對應的Container執行個體,這樣,就可以通過Resolve解析到注冊的類型執行個體。

同樣地,如果你修改資料庫類型注冊為:

builder.RegisterType<OracleDatabase>().As<IDatabase>();

運作結果:

​​

Ioc容器-Autofac 之四-依賴注入架構Autofac的簡單使用

​​

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

"

); 

運作結果:

​​

Ioc容器-Autofac 之四-依賴注入架構Autofac的簡單使用

​​

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 ...

"

); 

}

運作結果:

​​

Ioc容器-Autofac 之四-依賴注入架構Autofac的簡單使用

​​分析:

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" };

運作結果:

​​

Ioc容器-Autofac 之四-依賴注入架構Autofac的簡單使用

​​