关于Onion Structure?
1. 创建执行sql
Use [master] go IF NOT EXISTS (select name from master..syslogins where name='TemplateUser') BEGIN CREATE LOGIN [TemplateUser] WITH PASSWORD=N'pwd123', DEFAULT_DATABASE=[Template], DEFAULT_LANGUAGE=[us_english], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF ALTER LOGIN [TemplateUser] ENABLE END --== Add CapitalStructureAppUser login to DB ==-- USE [Template] CREATE USER [TemplateUser] FOR LOGIN [TemplateUser]; EXEC sp_addrolemember 'db_owner', 'TemplateUser' GO USE [Template] GO --============================================================-- --== Drop objects ==-- --============================================================-- IF EXISTS (SELECT TOP 1 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'Users') DROP TABLE [dbo].[Users] GO --============================================================-- --== Create Objcets ==-- --============================================================-- CREATE TABLE [dbo].[Users]( [UserID] [INT] IDENTITY(1,1) NOT NULL, [Name] [NVARCHAR](255) NOT NULL, [ModifiedBy] [NVARCHAR](128) NOT NULL CONSTRAINT [DF_User_ModifiedBy] DEFAULT ('SYSTEM'), [ModifiedAt] [DATETIME] NOT NULL CONSTRAINT [DF_User_ModifiedAt] DEFAULT (GETDATE()), CONSTRAINT [PK_User_UserID] PRIMARY KEY CLUSTERED ([UserID]) ON [PRIMARY], CONSTRAINT [UX_User_Name] UNIQUE NONCLUSTERED ([Name]) ON [PRIMARY] ) ON [PRIMARY] GO
2. 使用Mehdime.Entity创建DbContext相关
关于Mehdime.Entity?
Nuget上下载mehdime.entity,将对应文件复制到如下图
创建接口文件
创建Implementations文件
3. 创建DomainModel - User
public class User: ModelBase { public User() { } [Key] public int UserId { get; set; } [Required] public string Name { get; set; } }
4. 创建项目Context- TemplateContext
using System.Data.Entity; using System.Data.Common; using Domain.Models.Accounts; public class TemplateContext : DbContext { public TemplateContext() :base("name=Template") { Configuration.ProxyCreationEnabled = false; } public TemplateContext(DbConnection connection) : base(connection, false) { Configuration.ProxyCreationEnabled = false; } public virtual DbSet<User> Users { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { #region Table Name Mapping modelBuilder.Entity<User>().ToTable("User"); #endregion } }
1、创建Repository工厂
public interface IRepository<TEntity> where TEntity : class { IQueryable<TEntity> Query(); void Add(TEntity entity); void Update(TEntity entity); void Delete(TEntity entity); } public class Repository<TEntity> : IRepository<TEntity> where TEntity : class { private readonly DbContext _context; protected readonly IDbSet<TEntity> EntitySet; public Repository(DbContext context) { _context = context; EntitySet = _context.Set<TEntity>(); } public IQueryable<TEntity> Query() { return EntitySet; } public void Add(TEntity entity) { throw new NotImplementedException(); } public void Update(TEntity entity) { throw new NotImplementedException(); } public void Delete(TEntity entity) { throw new NotImplementedException(); } }
2、扩展DbContextExtensions
扩展DbContext,用于获取当前Repository
public static class DbContextExtensions { public static IRepository<TEntity> GetRepository<TEntity>(this DbContext context) where TEntity : class { return new Repository<TEntity>(context); } }
3、创建AccountRepository
日志接口暂时忽略ILoggerService
public interface IAccountRepository { IEnumerable<User> GetUsers(); } public class AccountRepository: ContextRepository, IAccountRepository { private readonly ILoggerService _logger; public AccountRepository(IAmbientDbContextLocator contextLocator, ILoggerService logger) : base(contextLocator) { _logger = logger; } public IEnumerable<User> GetUsers() { var dbUsers = Context.GetRepository<User>().Query().ToList(); return dbUsers; } }
创建对应的接口和类
1、接口
public interface IAccountService { IEnumerable<User> GetAllUsers(User requestingUser); }
2、服务类
public class AccountService : IAccountService { private readonly IAccountRepository _accountRepository; private readonly IDbContextScopeFactory _dbContextScopeFactory; public AccountService(IDbContextScopeFactory dbContextScopeFactory, IAccountRepository accountRepository) { _accountRepository = accountRepository; _dbContextScopeFactory = dbContextScopeFactory; } public IEnumerable<User> GetAllUsers(User requestingUser) { if (requestingUser == null) { throw new ArgumentNullException("requestingUser"); } using (_dbContextScopeFactory.CreateReadOnly()) { var userCollection = _accountRepository.GetUsers(); return userCollection; } } }
引用api的RoutePrefix需要更改System.Web.http引用路径,如下
<Reference Include="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath> </Reference>
1、创建基类AppApiController
用于获取当前User用户
public class AppApiController: ApiController { public User RequestUser { get { return (Domain.Models.Accounts.User) User; } } }
2、扩展ApiController
用于对结果数据进行统一封装和装饰,如mapper功能等。 Mapper功能后续补上
首先,创建自定义的IHttpActionResult返回结果。
a. 返回成功类
public class ApiFailActionResult : IHttpActionResult { private readonly string Message; public ApiFailActionResult(string message) { Message = message; } public Task<HttpResponseMessage> ExecuteAsync(System.Threading.CancellationToken cancellationToken) { return Task.FromResult(ExecuteResult()); } public HttpResponseMessage ExecuteResult() { var response = new HttpResponseMessage(HttpStatusCode.BadRequest); var Data = new { Success = false, Data = (object)null, Error = Message }; var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), Converters = new JsonConverter[] { new StringEnumConverter() } }; var jsonString = JsonConvert.SerializeObject(Data, settings); response.Content = new StringContent(jsonString); response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); return response; }
b. 返回失败类
public class ApiFailActionResult : IHttpActionResult { private readonly string Message; public ApiFailActionResult(string message) { Message = message; } public Task<HttpResponseMessage> ExecuteAsync(System.Threading.CancellationToken cancellationToken) { return Task.FromResult(ExecuteResult()); } public HttpResponseMessage ExecuteResult() { var response = new HttpResponseMessage(HttpStatusCode.BadRequest); var Data = new { Success = false, Data = (object)null, Error = Message }; var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), Converters = new JsonConverter[] { new StringEnumConverter() } }; var jsonString = JsonConvert.SerializeObject(Data, settings); response.Content = new StringContent(jsonString); response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); return response; } }
c. 扩展ApiController
public static class ApiControllerExtension { public static ApiOkActionResult ApiOkResult(this ApiController controller) { return new ApiOkActionResult(null); } public static ApiOkActionResult ApiOkResult<TResponseType>(this ApiController controller, object data) { if (data == null) { return ApiOkResult(controller); } //var mappedData = Mapper.Map<TResponseType>(data); return new ApiOkActionResult(data); } public static ApiFailActionResult ApiFailResult(this ApiController controller, string message) { return new ApiFailActionResult(message); } }
3、 添加一个Api方法
关于StructureMap的相关介绍和说明,可参照博文http://www.cnblogs.com/XmNotes/archive/2012/01/09/2317255.html,本文只阐明如何用到当前Project上。
未完待续.....