整个解决方案按照分层思想来划分不同功能模块,以提供User服务的Api为需求,各个层次的具体实现如下所示:
1、新建数据库User表
数据库使用SQLExpress版本,表的定义如下所示:
- CREATE TABLE [dbo].[User] (
- [Id] INT IDENTITY (1, 1) NOT NULL,
- [Name] NVARCHAR (50) NOT NULL,
- [Password] NVARCHAR (50) NOT NULL,
- [Age] INT NOT NULL,
- [Birthdate] DATE NOT NULL,
- [CreateTime] DATETIME DEFAULT (getdate()) NOT NULL,
- [CreateUserId] NVARCHAR (50) NOT NULL,
- [CreateUserName] NVARCHAR (50) NOT NULL,
- [ModifiedTime] DATETIME NULL,
- [ModifiedUserId] NVARCHAR (50) NULL,
- [ModifiedUserName] NVARCHAR (50) NULL,
- PRIMARY KEY CLUSTERED ([Id] ASC)
- );
2、实体层
新建类库类型的项目,.net framework框架版本4.5,User实体类如下:
- public class User
- {
- public int Id { get; set; }
- public string Name { get; set; }
- public string Password { get; set; }
- public int Age { get; set; }
- public DateTime Birthdate { get; set; }
- public DateTime CreateTime { get; set; }
- public string CreateUserId { get; set; }
- public string CreateUserName { get; set; }
- public DateTime? ModifiedTime { get; set; }
- public string ModifiedUserId { get; set; }
- public string ModifiedUserName { get; set; }
- }
3、数据库层
该层提供数据库接口操作,采用EntitFramework4.4.0.0作为ORM实体映射框架,
- public interface IRepository<TEntity> : IDisposable where TEntity : class
- {
- IEnumerable<TEntity> Get();
- IEnumerable<TEntity> Get(Expression
bool >> filter); - IEnumerable<TEntity> Get<TOderKey>(Expression
bool >> filter, int pageIndex, int pageSize, Expression> sortKeySelector, bool isAsc = true ); -
- int Count(Expression
bool >> predicate); - void Update(TEntity instance);
- void Add(TEntity instance);
- void Delete(TEntity instance);
- }
- public class BceDbContext:DbContext
- {
- public BceDbContext():base("DaLeiDB")
- {
- Database.SetInitializer
(null); - }
- public DbSet<User> Users { get; set; }
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- modelBuilder.Entity
().ToTable("User"); - base.OnModelCreating(modelBuilder);
- }
- }
- public class BceRepository<TEntity> : IRepository<TEntity> where TEntity : class
- {
- public BceDbContext DbContext { get; private set; }
- public DbSet
DbSet { get; private set; } - public BceRepository(BceDbContext context)
- {
- Guard.ArgumentNotNull(context, "context");
- this.DbContext = context;
- this.DbSet = this.DbContext.Set
(); - }
-
- public IEnumerable<TEntity> Get()
- {
- return this.DbSet.AsQueryable();
- }
- public IEnumerable<TEntity> Get(Expression
bool >> filter) - {
- return this.DbSet.Where(filter).AsQueryable();
- }
- public IEnumerable<TEntity> Get<TKey>(Expression
bool >> filter, int pageIndex, int pageSize, Expression> sortKeySelector, bool isAsc = true ) - {
- Guard.ArgumentNotNull(filter, "predicate");
- Guard.ArgumentNotNull(sortKeySelector, "sortKeySelector");
- if (isAsc)
- {
- return this.DbSet
- .Where(filter)
- .OrderBy(sortKeySelector)
- .Skip(pageSize * (pageIndex - 1))
- .Take(pageSize).AsQueryable();
- }
- else
- {
- return this.DbSet
- .Where(filter)
- .OrderByDescending(sortKeySelector)
- .Skip(pageSize * (pageIndex - 1))
- .Take(pageSize).AsQueryable();
- }
- }
-
- public int Count(Expression
bool >> predicate) - {
- return this.DbSet.Where(predicate).Count();
- }
-
- public void Add(TEntity instance)
- {
- Guard.ArgumentNotNull(instance, "instance");
- this.DbSet.Attach(instance);
- this.DbContext.Entry(instance).State = EntityState.Added;
- this.DbContext.SaveChanges();
- }
- public void Update(TEntity instance)
- {
- Guard.ArgumentNotNull(instance, "instance");
- this.DbSet.Attach(instance);
- this.DbContext.Entry(instance).State = EntityState.Modified;
- this.DbContext.SaveChanges();
- }
- public void Delete(TEntity instance)
- {
- Guard.ArgumentNotNull(instance, "instance");
- this.DbSet.Attach(instance);
- this.DbContext.Entry(instance).State = EntityState.Deleted;
- this.DbContext.SaveChanges();
- }
-
- public void Dispose()
- {
- this.DbContext.Dispose();
- }
- }
- namespace DaLei.Repository
- {
- public interface IUserRepository
- {
- User FindByName(string name);
- List
FindByAge(int start, int end) ; - }
- }
- namespace DaLei.Repository
- {
- public class UserRepository : BceRepository<User>, IUserRepository
- {
- public UserRepository(BceDbContext bceDbContext):base(bceDbContext)
- {
-
- }
-
- public List
FindByAge(int start, int end) - {
- var rst = this.DbSet.AsQueryable().Where(u=>u.Age>=start && u.Age<=end).ToList();
- return rst;
- }
-
- public User FindByName(string name)
- {
- var rst = this.DbSet.AsQueryable().Where(u => u.Name == name).FirstOrDefault();
- return rst;
- }
- }
- }
4、服务接口层
定义了对外提供用户服务的接口契约,具体如下:
- namespace DaLei.IService
- {
- public interface IUserService
- {
- User FindByName(string name);
- List
FindByAge(int start, int end) ; - List
GetList() ; - }
- }
5、服务具体实现层
服务基类实现:
- using System;
- using System.Collections.Generic;
-
- namespace DaLei.Service
- {
- public abstract class ServiceBase : IDisposable
- {
- public IList
DisposableObjects { get; private set; } - public ServiceBase()
- {
- this.DisposableObjects = new List
(); - }
- protected void AddDisposableObject(object obj)
- {
- IDisposable disposable = obj as IDisposable;
- if (null != disposable)
- {
- this.DisposableObjects.Add(disposable);
- }
- }
-
- public void Dispose()
- {
- foreach (IDisposable obj in this.DisposableObjects)
- {
- if (null != obj)
- {
- obj.Dispose();
- }
- }
- }
- }
- }
用户服务接口具体实现:
- using DaLei.IService;
- using DaLei.Model;
- using DaLei.Repository;
- using System.Collections.Generic;
-
- namespace DaLei.Service
- {
- public class UserService : ServiceBase,IUserService
- {
- private IUserRepository userRepository;
- public UserService(IUserRepository userRepository)
- {
- this.userRepository = userRepository;
- this.AddDisposableObject(userRepository);
- }
- public List
FindByAge(int start, int end) - {
- return this.userRepository.FindByAge(start,end);
- }
-
- public User FindByName(string name)
- {
- return this.userRepository.FindByName(name);
- }
-
- public List
GetList() - {
- return this.userRepository.FindByAge(0, 100);
- }
- }
- }
6、应用层
新建Asp.net WebApi项目,引用服务接口项目、服务实现项目、实体类项目,unity相关程序集,EntityFramework程序集。

web.config配置连接字符串和unity相关内容:
- "1.0" encoding="utf-8"?>
- <configuration>
- <configSections>
- <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
- configSections>
- <unity>
- <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />
- <containers>
- <container>
- <extension type="Interception" />
- <register type="DaLei.IService.IUserService, DaLei.IService" mapTo="DaLei.Service.UserService, DaLei.Service" />
- <register type="DaLei.Repository.IUserRepository, DaLei.Repository" mapTo="DaLei.Repository.UserRepository, DaLei.Repository">
- <interceptor type="InterfaceInterceptor" />
- <policyInjection />
- register>
- container>
- containers>
- unity>
- <connectionStrings>
- <add name="DaLeiDB" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=DaleiDB;User ID=sa;Password=anpiel0991;" providerName="System.Data.SqlClient" />
- connectionStrings>
- <appSettings>
- <add key="webpages:Version" value="3.0.0.0"/>
- <add key="webpages:Enabled" value="false"/>
- <add key="PreserveLoginUrl" value="true"/>
- <add key="ClientValidationEnabled" value="true"/>
- <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
- appSettings>
- <system.web>
- <compilation debug="true" targetFramework="4.5"/>
- <httpRuntime targetFramework="4.5"/>
- <pages>
- <namespaces>
- <add namespace="System.Web.Helpers"/>
- <add namespace="System.Web.Mvc"/>
- <add namespace="System.Web.Mvc.Ajax"/>
- <add namespace="System.Web.Mvc.Html"/>
- <add namespace="System.Web.Routing"/>
- <add namespace="System.Web.WebPages"/>
- namespaces>
- pages>
- system.web>
- <system.webServer>
- <validation validateIntegratedModeConfiguration="false"/>
- <handlers>
- <remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
- <remove name="OPTIONSVerbHandler"/>
- <remove name="TRACEVerbHandler"/>
- <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler"
- preCondition="integratedMode,runtimeVersionv4.0"/>
- handlers>
- system.webServer>
- <runtime>
- <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
- <dependentAssembly>
- <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed"/>
- <bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0"/>
- dependentAssembly>
- <dependentAssembly>
- <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/>
- <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
- dependentAssembly>
- <dependentAssembly>
- <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
- <bindingRedirect oldVersion="1.0.0.0-5.2.7.0" newVersion="5.2.7.0"/>
- dependentAssembly>
- <dependentAssembly>
- <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35"/>
- <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0"/>
- dependentAssembly>
- <dependentAssembly>
- <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
- <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
- dependentAssembly>
- <dependentAssembly>
- <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35"/>
- <bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930"/>
- dependentAssembly>
- assemblyBinding>
- runtime>
- <system.codedom>
- <compilers>
- <compiler language="c#;cs;csharp" extension=".cs"
- type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
- warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701"/>
- <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
- type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
- warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+"/>
- compilers>
- system.codedom>
- configuration>
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- using System.Web.Routing;
- using Microsoft.Practices.Unity;
- using Microsoft.Practices.Unity.Configuration;
- using System.Configuration;
-
- namespace WebApi.Extensions
- {
- public class UnityControllerFactory : DefaultControllerFactory
- {
- static object syncHelper = new object();
- static Dictionary<string, IUnityContainer> containers = new Dictionary<string, IUnityContainer>();
- public IUnityContainer UnityContainer { get; private set; }
- public UnityControllerFactory(string containerName = "")
- {
- if (containers.ContainsKey(containerName))
- {
- this.UnityContainer = containers[containerName];
- return;
- }
- lock (syncHelper)
- {
- if (containers.ContainsKey(containerName))
- {
- this.UnityContainer = containers[containerName];
- return;
- }
- IUnityContainer container = new UnityContainer();
- //配置UnityContainer
- UnityConfigurationSection configSection = ConfigurationManager.GetSection(UnityConfigurationSection.SectionName) as UnityConfigurationSection;
- if (null == configSection && !string.IsNullOrEmpty(containerName))
- {
- throw new ConfigurationErrorsException("The
configuration section does not exist." ); - }
- if (null != configSection)
- {
- if (string.IsNullOrEmpty(containerName))
- {
- configSection.Configure(container);
- }
- else
- {
- configSection.Configure(container, containerName);
- }
- }
- containers.Add(containerName, container);
- this.UnityContainer = containers[containerName];
- }
- }
- protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
- {
- if (null == controllerType)
- {
- return null;
- }
- return (IController)this.UnityContainer.Resolve(controllerType);
- }
- //public override void ReleaseController(IController controller)
- //{
- // this.UnityContainer.Teardown(controller);
- //}
- }
- }
- using webApi.Extensions;
- using System;
- using System.Web;
- using System.Web.Http;
- using System.Web.Mvc;
- using System.Web.Routing;
-
- namespace WebApp
- {
- public class Global : HttpApplication
- {
- void Application_Start(object sender, EventArgs e)
- {
- // 在应用程序启动时运行的代码
- AreaRegistration.RegisterAllAreas();
- GlobalConfiguration.Configure(WebApiConfig.Register);
- RouteConfig.RegisterRoutes(RouteTable.Routes);
- ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory());
- }
- }
- }
- using WebApi.Extensions;
- using System.Web.Mvc;
- using System;
- using System.Collections.Generic;
-
- namespace WebApp.Controllers
- {
- public class BaseController:Controller
- {
- public IList
DisposableObjects { get; private set; } - public BaseController()
- {
- this.DisposableObjects = new List
(); - }
- protected void AddDisposableObject(object obj)
- {
- IDisposable disposable = obj as IDisposable;
- if (null != disposable)
- {
- this.DisposableObjects.Add(disposable);
- }
- }
-
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- foreach (IDisposable obj in this.DisposableObjects)
- {
- if (null != obj)
- {
- obj.Dispose();
- }
- }
- }
- base.Dispose(disposing);
- }
- }
- }
- using DaLei.IService;
- using System.Web.Mvc;
-
- namespace WebApp.Controllers
- {
- public class TestController : BaseController
- {
- private IUserService userService;
- public TestController(IUserService userService)
- {
- this.userService = userService;
- this.AddDisposableObject(userService);
- }
-
- // GET: Test
- public ActionResult Index()
- {
- var users = this.userService.GetList();
- return View();
- }
- }
- }
浏览器输入地址测试TestController!