mvc学习总结-使用Ninject和CodeFirst

1.Ninject用来解耦程序;即对接口编程,而不是对实现类编程;理解:BLL对IDAL编程,对应的是调用多种数据实现的DAL,DAL可以是SqlServer的,可以是Oracle,或其他数据媒介;

2.CodeFirst是EF的一种;用来实现数据持久化,可以理解为第一点中的DAL层或repository层的数据来源;

3.主要代码

model层

namespace MVCCodeFirstNinject.Model
{
    public class EntityBase<TId>
    {
        public TId ID { get; set; }
    }
}

  

namespace MVCCodeFirstNinject.Model
{
    public class Product : EntityBase<int>
    {
        public string Name { get; set; }
        public decimal Price { get; set; }
    }
}

irepository层,我把仓储的接口层独立出来,看到很多人都是放到domain中的;

namespace MVCCodeFirstNinject.IRepository
{
    public interface IProductRepository
    {
        IQueryable<Product> Products { get; }
    }
}

  这里返回IQueryable,理解:IQueryable处理sql时会加入where,而IEumerable是把所有数据读取到内存再进行where过滤,当然IQueryable在处理linq转换where时会消耗性能;因此:IQueryable用于数据多,反之IEumerable;

EF的CodeFirst独立出来,做数据层:CodeFirst需要添加EF引用;

namespace MVCCodeFirstNinject.CodeFirst
{
    public class EFDbContext : DbContext
    {
        public DbSet<Product> Products { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Product>().ToTable("tProduct");//指定表名
            //设置对应到数据库的字段名
            modelBuilder.Entity<Product>()
                .Property(p => p.ID)
                .HasColumnName("ProductID")
                .HasColumnType("int");
        }
    }
}

  还需要在web.config增加连接串:

<connectionStrings>
        <add name="EFDbContext" connectionString="Data Source=.;Initial Catalog=Product;User ID=sa;Password=sa" providerName="System.Data.SqlClient" />
    </connectionStrings>

  如上两步就实现了CodeFirst的数据读取;

增加repository层,这里理解成:多种数据来源定义不同的仓储,比如现在是用CodeFirst的(即这里调用CodeFirst实现数据持久化),以后程序拓展,可以拓展成其他层,比如三层用SqlServer的DAL,或Oracle;

namespace MVCCodeFirstNinject.Repository
{
    public class ProductRepository : IProductRepository
    {
        private EFDbContext ef = new EFDbContext();

        public IQueryable<Product> Products
        {
            get { return ef.Products; }
        }
    }
}

接着是基础设备,定义mvc接入的开头工厂类,这里定义在infrastructure层:

namespace MVCCodeFirstNinject.Infrastructure
{
    //基础设施层:指定mvc映射的Ninject工厂模式
    //作用就是用mvc模式调用Ninject来映射控制器中应该使用的某个视图,
    //因此如若是多视图,应该是该视图下包含多个子视图,以此来达到一个页面显示多种model数据
    public class NinjectControllerFactory : DefaultControllerFactory
    {
        private IKernel ik;

        public NinjectControllerFactory()
        {
            ik = new StandardKernel();
            AddNinjectIoc();
        }

        private void AddNinjectIoc()
        {
            ik.Bind<IProductRepository>().To<ProductRepository>();
        }

        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            //ik.Get 得到依赖注入的接口对应的类
            return controllerType == null ? null : (IController)ik.Get(controllerType);
        }
    }
}

  这里包括了Ninject的使用,即先定义ik,然后用bind指定映射;最后是重新mvc的接入方法,用get方法来返回所要使用的类,即仓储中的IRepository类;

最后是mvc,在mvc中加入Ninject的工厂模式注册:

namespace MVCCodeFirstNinject.Web
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            //加入Ioc的调用
            ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
        }
    }
}

接着添加mvc控制器:(mvc就是添加控制器,然后在控制器方法中添加对应的视图)

namespace MVCCodeFirstNinject.Web.Controllers
{
    public class ProductController : Controller
    {
        private IProductRepository _repository;

        //
        // GET: /Product/
        public ViewResult Index()
        {
            return View(_repository.Products);
        }
       
        public ProductController(IProductRepository repository)
        {
            _repository = repository;
        }
    }
}

  控制器的构造函数,引入了对应的IProductRepository的初始化(映射来源于基础设备层的工厂类,注意该类的继承和重新),得到了对应的数据层读取(这里即:对接口编程);

最后是添加视图,即可读取数据了:

@model IQueryable<MVCCodeFirstNinject.Model.Product>
@{
    ViewBag.Title = "Index";
}
@{
    string str = "";
    foreach (var p in Model)
    {
        str += "<p>" + p.Name + "</p>";
    }    
}
@str

  

posted @ 2014-07-25 09:42  童俊江  阅读(517)  评论(0编辑  收藏  举报