Autofac -入门练习
1.创建一个控制台项目 AutofacConsole
2.创建文件夹Abstract,在文件夹中创建接口
namespace AutofacConsole.Abstract
{
public interface IDatabase
{
string Name { get; }
void Select(string commandText);
void Insert(string commandText);
void Update(string commandText);
void Delete(string commandText);
}
}
3.创建文件夹Data,在文件夹中分别创建类文件SqlServerDatabase.cs 和MySqlDatabase.cs
using AutofacConsole.Abstract;
using System;
namespace AutofacConsole.Data
{
public class MySqlDatabase : IDatabase
{
public string Name
{
get
{
return "MySql";
}
}
public void Delete(string commandText)
{
Console.WriteLine(string.Format("{0} is a delete 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 Select(string commandText)
{
Console.WriteLine(string.Format("{0} is a select sql in {1}", commandText, Name));
}
public void Update(string commandText)
{
Console.WriteLine(string.Format("{0} is a update sql in {1}", commandText, Name));
}
}
}
using AutofacConsole.Abstract;
using System;
namespace AutofacConsole.Data
{
public class SqlDatabase : IDatabase
{
public string Name
{
get
{
return "SqlServer";
}
}
public void Delete(string commandText)
{
Console.WriteLine(string.Format("{0} is a delete 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 Select(string commandText)
{
Console.WriteLine(string.Format("{0} is a query sql in {1}",commandText,Name)) ;
}
public void Update(string commandText)
{
Console.WriteLine(string.Format("{0} is a update sql in {1}", commandText, Name));
}
}
}
4.在文件夹Data中,创建类DatabaseManager.cs
using AutofacConsole.Abstract;
namespace AutofacConsole.Data
{
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.Insert(commandText);
}
public void Remove(string commandText)
{
_database.Delete(commandText);
}
}
}
5.在控制台程序中增加依赖注入代码
安装autofac:install-package autofac -version 5.2.0
using Autofac;
using AutofacConsole.Abstract;
using AutofacConsole.Data;
using System;
namespace AutofacConsole
{
class Program
{
static void Main(string[] args)
{
RegisterResolver();
Console.ReadLine();
}
static void RegisterResolver()
{
var builder = new ContainerBuilder();
builder.RegisterType<DatabaseManager>();//注册实现类
builder.RegisterType<SqlDatabase>().As<IDatabase>(); //这样注册以后,DatabaseManager就可以通过构造器注入了
using (var container = builder.Build()) //返回IContainer对象
{
var manager = container.Resolve<DatabaseManager>(); //得到注册的类型的对象
manager.Search("select * from user");
}
}
}
}
这里通过ContainerBuilder方法RegisterType对DatabaseManager进行注册,当注册的类型在相应的容器中可以Resolve你的DatabaseManager实例。
builder.RegisterType<SqlDatabase>().As<IDatabase>();通过AS可以让DatabaseManager类中通过构造函数依赖注入类型相应的接口。
Build()方法生成一个对应的Container实例,这样,就可以通过Resolve解析到注册的类型实例。
IContainer.Resolver<IDAL> 解析某个接口的实。例如 var manager = container.Resolve<DatabaseManager>();
builder.RegisterType<Object>().Named<IObject>(string name):为一个接口注册不同的实例,有时候难免碰到多个类映射同一个接口,比如SqlServer和Oracle都是实现了IDalSouce接口,为了获取想要的类型,就必须在注册时起名字。
var builder=new ContainerBuilder();
builder.RegisterType<SqlServer>().Named<IDalSouce>("SqlServer");
builder.RegiserType<Oracle>().Named<IDalSouce>("Oracle")
using(var container=builder.Build())
{
var manager=container.ResolverNamed<IDalSource>("Oracle"); //根据不同的参数获取不同的实例
Console.WriteLine(manager.GetData());
Console.WriteLine();
}
IContainer.ResolveKeyed<IDAL>(Enum enum):根据枚举值解析某个接口的特性实例,和Named差不多。
builder.RegisterType<Worker>().InstancePerDependency():用于控制对象的生命周期,每次加载实例时都创建一个新的实例,默认就是这种方式。
如:builder.RegisterType<SqlServer>().Keyed<IDataSource>("SqlServer").InstancePerDependency()
builder.RegisterType<Work>().SingleInstance():用于控制对象的生命周期,每次加载实例时都返回同一个实例。
IContainer.Resolver<T>(NamedParameter namedParameter):在解析实例T时给其赋值,这个就是你定义的方法的参数值。
autofac-MVC
//创建autofac管理注册类容器实例
var builder=new ContianerBuilder()
//下面就需要为这个容器注册它可以管理的类型
builder.RegisterType<SqlServer>().As<IDatabase>();
//builder.RegisterType<DefaultController>().InstancePerDependency()
//使用Autofac提供的RegisterControllers扩展方法来对程序集中所有的Controller一次行完成注册
builder.RegisterControllers(Assembly.GetExeccutingAssembly());
//生成具体的实例
var container=builder.Build();
//下面就是用 MVC的扩展,更改MVC的注入方式 引用 System.Web.Mvc
DependencyResolver.SetResolver(new AutofacDependencyResolver(container))//ninject 注入时传入的是kernel
其中:
//使用Autofac提供的RegisterControllers扩展方法来对程序集中所有的控制器Controller一次性完成注册
builder.RegisterControllers(Assembly.GetExecutingAssembly());
我们通过使用RegisterControllers就可以解决注入。
builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired()属性注入
自动注入
Autofac提供了一个RegisterAssemblyTypes方法,它会去扫描所有的dll并把每个类注册为它所实现的接口。既然能够自动注入,那么接口和类的定义一定要有一定的规律,我们可以定义IDependency接口的类型,其他任何的接口都需要继承这个接口。
首先我们去找到所有的dll,再去找到实现了IDependency接口的类,然后使用Register.AssemblyTypes进行注册。
如:
Assembly[] asmbiles=Directory.GetFiles(AppDomain.CurrentDomian.RelativeSearch,"dll").Select(Assembly.LoadFrom).toArray();
//注册所有的实现了IDependency接口的类型
Type baseType=typeof(IDependency);
builder.RegisterAssemblyTypes(assimblies)
.Where(type=>baseType.IsAssignableFrom(type)&&!type.IsAbstract)
.AsSelf().AsImplementedInterfaces()
.PropertiesAutowired().InstancePerLifetimeScore();
//注册类型
builder.RegisterControllers(assmblies).PropertiesAutowired();
builder.RegisterFilterProvider();
var container=new Builder()
DependencyResolver.SetReolver(new AutofacDepenencyResolver(container));