控制反转(Inversion of Control,英文缩写为IoC)是框架的重要特征,并非面向对象编程的专用术语。它与依赖注入(Dependency Injection,简称DI)和依赖查找
(Dependency Lookup)并没有关系。简单地说,就是应用本身不负责依赖对象的创建和维护,而交给一个外部容器来负责。这样控制权就由应用转移到了外部IoC容器,
控制权就实现了所谓的反转。
一、引用Unity
将IoC应用于HttpController激活系统的目的在于让一个预定义的IoC容器来提供最终的HttpController对象
引用NuGet包的Unity
然后在 Web API应用中定义了这个UnityHttpControllerActivator类型。UnityHttpControllerActivator具有一个表示Unity容器的属性UnityContainer,该属性在构造函数
中被初始化。在用于创建的HttpController的Create方法中,我们调用此UnityContainer对象的Resolve方法创建目标HttpController对象。
public class UnityHttpControllerActivator :IHttpControllerActivator
{
public IUnityContainer UnityContainer { get; private set; }
public UnityHttpControllerActivator(IUnityContainer unityContainer)
{
this.UnityContainer = unityContainer;
}
public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
return (IHttpController)this.UnityContainer.Resolve(controllerType);
}
}
接下来我们定义了如下一个继承自ApiController的UserController来简单起见
[RoutePrefix("api/WeChat")]
public class UserController : ApiController
{
public IUserRepository IUser { get; private set; }
public UserController(IUserRepository IUser)
{
this.IUser = IUser;
}
[Route("UserSync")]
[HttpPost]
public ApiResultModel UserSync()
{
return IUser.UserSync();
}
[Route("UserDelete")]
[HttpPost]
public ApiResultModel UserDelete(RequestModel user)
{
return IUser.UserDelete(user);
}
}
public interface IUserRepository
{
/// <summary>
/// UserSync
/// </summary>
/// <returns></returns>
ApiResultModel UserSync();
/// <summary>
/// UserDelete
/// </summary>
/// <returns></returns>
ApiResultModel UserDelete(RequestModel user);
}
创建UserRepository
public class UserRepository: IUserRepository
{
public ApiResultModel UserSync()
{
//逻辑代码
}
public ApiResultModel UserDelete(RequestModel user)
{
//逻辑代码
}
}
最后在项目的Global.aspx的自定义的UnityHttpControllerActivator进行了注册。如下所示,我们在Application_Start方法中创建了一个UnityContainer对象,并通过调用泛型方
法RegisterType<TFrom,TTo>注册了IUserRepository接口和UserRepository类型之间的匹配关系。我们最后根据这个UnityContainer创建一个UnityHttpControllerActivator对象,并将其注册到当前ServicesContainer上。
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
// 使api返回为json
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
//ioc 配置
IUnityContainer unityContainer = new UnityContainer();
unityContainer.RegisterType<IAccountRepository, AccountRepository>();
unityContainer.RegisterType<IApprovalRepository, ApprovalRepository>();
unityContainer.RegisterType<IMessageRepository, MessageRepository>();
unityContainer.RegisterType<IAttendanceRepository, AttendanceRepository>();
unityContainer.RegisterType<ISalaryRepository, SalaryRepository>();
unityContainer.RegisterType<IDepartmentRepository, DepartmentRepository>();
unityContainer.RegisterType<ITagRepository, TagRepository>();
unityContainer.RegisterType<IUserRepository, UserRepository>();
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new Common.UnityHttpControllerActivator(unityContainer));
}
一、引用Autofac
首先 还是引入Autofac 包
Global.aspx
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
//ioc
var builder = new ContainerBuilder();
SetupResolveRules(builder);
builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly());
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
创建方法SetupResolveRules 用于获取当前 的依赖注入,
private void SetupResolveRules(ContainerBuilder builder)
{
var Inter = new List<Type>();
Assembly assembly = Assembly.Load("Car.Core.IRepository");
foreach (Type aaa in assembly.GetTypes())
{
if (aaa.Name.StartsWith("I") && aaa.Name.EndsWith("Repository"))
{
Inter.Add(aaa);
}
}
var entity = new List<Type>();
Assembly entassembly = Assembly.Load("Car.Core.Repository");
foreach (Type aaa in entassembly.GetTypes())
{
if (aaa.Name.EndsWith("Repository"))
{
entity.Add(aaa);
}
}
foreach (var item in entity)
{
Inter.ForEach(a =>
{
if (a.Name.Contains(item.Name))
{
builder.RegisterType(item).As(a);
}
});
}
}