天天看点

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的简单使用

​​