MVC+Entity Framework Code First+AutoFac实现依赖注入

AutoFac介绍

Autofac是一个.net平台下发性能还不错的IoC框架,利用它可以实现依赖注入和控制反转,使自己的软件模块之间的耦合性大大降低,让软件扩展、维护更加容易。控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题。

依赖注入介绍

依赖注入模式是一种控制反转的实现,那什么是控制反转呢?控制反转的意思是对象不直接创建它要完成某些功能所依赖的其它对象。相反的它通过外部来获取创建这些对象(比如:xml配置文件,其它框架api等等)。
采用依赖注入一个最大的特点是其中是没有对象直接介入的,一般情况是通过框架来对有构造函数的参数或者属性来注入相应的对象。

用依赖注入和控制反转的好处:

  1. 减少类的耦合性
  2. 提高代码的重用性
  3. 提高代码的可维护性
  4. 提高代码的可测试性

下面介绍下使用MVC+Entity Framework+AutoFac来实现依赖注入

实现介绍

Framework Code First实现

创建Model和数据库上下文

这个没什么难度.直接贴代码了
model:

using MVCBlog.Entities.Enums;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MVCBlog.Entities.Models
{
    [Table("PostInfo")]
    public class PostInfo
    {
        [Key]
        public int Id { get; set; }
        [Required]
        public string Title { get; set; }
        [Required]
        public string Content { get; set; }
        public PostStatus PostStatus { get; set; }
        public PostType PostType { get; set; }
        public CommentStatus CommentStatus { get; set; }
        public int CommentCount { get; set; }
        public virtual UserInfo PostAuthor { get; set; }
        public virtual ICollection<CommentInfo> CommentInfos { get; set; }
        public virtual ICollection<PostMetasInfo> PostMetasInfos { get; set; }
        public DateTime? EditedTime { get; set; }
        public DateTime CreateTime { get; set; }
        public bool IsDelete { get; set; }
    }
}

数据库上下文 MVCBlogContext:

using System.Data.Entity;
using MVCBlog.Entities.Models;
namespace MVCBlog.Repository
{
    [DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
    public class MVCBlogContext : DbContext
    {
        public MVCBlogContext() : base("name=DefaultConnection")
        {
            // this.Configuration.ValidateOnSaveEnabled = false;
        }
        public DbSet<CategoryInfo> CategoryInfo { get; set; }
        public DbSet<CategoryRelationships> CategoryRelationships { get; set; }
        public DbSet<CommentInfo> CommentInfo { get; set; }
        public DbSet<PostInfo> PostInfo { get; set; }
        public DbSet<PostMetasInfo> PostMetasInfo { get; set; }
        public DbSet<UserInfo> UserInfo { get; set; }
    }
}

安装EntityFramework

由于我使用的是mysql作为数据库.所以直接nuget包控制台安装:

Install-Package MySQL.Data.Entities

web.config添加连接字符串

<connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=192.168.28.130;port=3306;          Initial Catalog=mvcblog;user id=root;           password=root;Allow Zero Datetime=True;Character Set=utf8;" providerName="MySql.Data.MySqlClient" />
  </connectionStrings>  

然后重新生成下解决方案.如果没有错误就可以进行下一步了.

生成数据库

还是在nuget包控制台.依次输入下面命令

Enable-Migrations
add-migration Initial
update-database  

如果成功生成了数据库,那么就可以进行下一步了.
如果有错误.可以看看我以前写的这篇文章 Mvc使用EntityFramework和Mysql错误总结 里面记录了几个以前遇到的错误和解决办法.

AutoFac依赖注入实现

安装AutoFac

nuget安装.包管理器中搜索AutoFac.MVC5并安装.

具体实现

接口部分.直接贴代码

using System.Collections.Generic;
using MVCBlog.Entities.Models;
namespace MVCBlog.Service.Interfaces
{
    public interface IPostService
    {
        List<PostInfo> GetPosts();
        PostInfo GetById(int id);
        void Insert(PostInfo model);
        void Update(PostInfo model);
        void Delete(PostInfo model);
    }
}

接口实现类

using System;
using System.Collections.Generic;
using System.Linq;
using MVCBlog.Entities.Models;
using MVCBlog.Service.Interfaces;
using MVCBlog.Repository;
using MVCBlog.Entities.Enums;
namespace MVCBlog.Service
{
    public class PostService : IPostService
    {
        private MVCBlogContext Context;
        public PostService(MVCBlogContext _contest)
        {
            this.Context = _contest;
        }

        public void Delete(PostInfo model)
        {
            if (model!=null)
            {
                var entity = Context.PostInfo.Find(model.Id);
                entity.IsDelete = true;
                entity.PostStatus = PostStatus.删除;
                Context.SaveChanges();
            }
        }

        public PostInfo GetById(int id)
        {
            var entity = Context.PostInfo.Find(id);
            return entity;
        }

        public List<PostInfo> GetPosts()
        {
            return Context.PostInfo.ToList();
            //return Context.PostInfo.Where(x => !x.IsDelete && x.PostStatus == PostStatus.发布).ToList();
        }

        public void Insert(PostInfo model)
        {
            Context.PostInfo.Add(model);
            Context.SaveChanges();
        }

        public void Update(PostInfo model)
        {
            var entity = Context.PostInfo.Find(model.Id);
            entity.Title = model.Title;
            entity.Content = model.Content;
            entity.PostStatus = model.PostStatus;
            entity.CommentStatus = model.CommentStatus;
            entity.EditedTime = DateTime.Now;
            Context.SaveChanges();
        }
    }
}

在MVC项目中创建DependencyDependencyConfigure两个类.具体如下.
Dependency类:

using Autofac;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

namespace MVCBlog.Web.Infrastructure
{
    public class Dependency : IDependencyResolver
    {
        private readonly IContainer container;

        public Dependency(IContainer container)
        {
            this.container = container;
        }

        public object GetService(Type serviceType)
        {
            return
                container.IsRegistered(serviceType)
                    ? container.Resolve(serviceType)
                    : null;
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {

            Type enumerableServiceType =
                typeof (IEnumerable<>).MakeGenericType(serviceType);

            object instance =
                container.Resolve(enumerableServiceType);

            return ((IEnumerable) instance).Cast<object>();
        }
    }
}

DependencyConfigure类:

using Autofac;
using MVCBlog.Repository;
using MVCBlog.Service;
using MVCBlog.Service.Interfaces;
using System.Web.Mvc;
namespace MVCBlog.Web.Infrastructure
{
    internal class DependencyConfigure
    {
        public static void Initialize()
        {
            var builder = new ContainerBuilder();
            DependencyResolver.SetResolver(
                new Dependency(RegisterServices(builder))
                );
        }

        private static IContainer RegisterServices(ContainerBuilder builder)
        {

            builder.RegisterAssemblyTypes(
                typeof(MvcApplication).Assembly
                ).PropertiesAutowired();

            //注册上下文.每次都会创建不同的实例
            builder.RegisterType<MVCBlogContext>().As<MVCBlogContext>().InstancePerDependency();

            //注册PostService
            //这里通过ContainerBuilder方法RegisterType进行注册.当注册的类型在相应得到的容器中可以Resolve你的实例
            //通过AS可以通过构造函数依赖注入类型相应的接口
            builder.RegisterType<PostService>().As<IPostService>();
            //Build()方法生成一个对应的Container实例,这样,就可以通过Resolve解析到注册的类型实例
            return builder.Build();
        }


    }
}  

修改Globa.asax.如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using MVCBlog.Repository;
using Autofac;
using Autofac.Integration.Mvc;
using MVCBlog.Web.Infrastructure;

namespace MVCBlog.Web
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            DependencyConfigure.Initialize();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
        }

    }
}

至此.基本上已经完成了.使用的话在控制器中用下面的方法来使用.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVCBlog.Service.Interfaces;
namespace MVCBlog.Web.Controllers
{
    public class HomeController : Controller
    {
        private readonly IPostService _postService;

        public HomeController(IPostService postService)
        {
            _postService = postService;
        }
        // GET: Home
        public ActionResult Index()
        {
            var test = _postService.GetPosts();
            return View();
        }
    }
}  

发表评论

电子邮件地址不会被公开。 必填项已用*标注