webapi配置
- protectedvoidApplication_Start()
- {
- AreaRegistration.RegisterAllAreas();
- //SwaggerConfig.Register();
- GlobalConfiguration.Configure(WebApiConfig.Register);
- //Nhibernate及日志初始化
- LoggingConfig.Register();
- //依赖注入初始化
- IocConfig.Register();
- }
在Global.asax的启动方法中加入依赖注入的配置,NHibernate配置,以及webapi配置,区域路由配置等,如果使用安全策略也许要在此加入,本例目前还没进行身份认证处理,后面将会重点介绍。
AutoFac依赖注入配置
- publicstaticvoidRegister()
- {
- ContainerBuilderbuilder=newContainerBuilder();
- TypebaseType=typeof(IDependency);
- varassemblies=AppDomain.CurrentDomain.GetAssemblies();
- //获取所有相关类库的程序集
- builder.RegisterAssemblyTypes(assemblies)
- .Where(type=>baseType.IsAssignableFrom(type)&&!type.IsAbstract)
- .AsImplementedInterfaces()
- .InstancePerLifetimeScope();
- varconfig=GlobalConfiguration.Configuration;
- builder.RegisterWebApiFilterProvider(config);
- builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
- //builder.RegisterType<GroupListController>().InstancePerRequest();
- varcontainer=builder.Build();
- config.DependencyResolver=newAutofacWebApiDependencyResolver(container);
- }
这个配置可以看出是利用反射技术获取当前应用下的所有assemblies,通过TypebaseType=typeof(IDependency)指定凡是继承该接口的实例都将注入到ContainerBuilder容器中。
除此之外,要在wabapi中使用依赖注入还需处理webapi的注入,这就需要使用另一个工具Autofac.WebApi,使用PM > Install-Package Autofac.WebApi获取。然后使用config.DependencyResolver=newAutofacWebApiDependencyResolver(container)就可将webapi的controller注入到容器中。
NHibernate配置
- publicclassLoggingConfig
- {
- publicstaticvoidRegister()
- {
- SessionBuilder.Instance("web");
- stringlogfile=CachedConfigContext.Current.ConfigService.GetFilePath("log4net");
- varms=newMemoryStream(Encoding.Default.GetBytes(logfile));
- log4net.Config.XmlConfigurator.ConfigureAndWatch(newFileInfo(logfile));
- }
- }
这里我还是用了log4net加入了log功能,这里注意SessionBuilder.Instance("web");由于我们开发的是webapi应用所以这里实例话是选择为web。这里的SessionBuilder是前面封装的对Nhibernate的ISession管理的类。
Web Api跨域访问配置
Web api跨越访问需要使用另外一个工具
PM>install-package Microsoft.AspNet.WebApi.Cors
在global中的webapi register中增加
var cors = newEnableCorsAttribute(
origins: "*",
headers: methods: );
config.EnableCors(cors);
- publicstaticclassWebApiConfig
- {
- publicstaticvoidRegister(HttpConfigurationconfig)
- {
- //WebAPI跨域访问
- varcors=newEnableCorsAttribute(
- origins:"*",
- headers:"*",
- methods:"*");
- config.EnableCors(cors);
- //WebAPI路由
- config.MapHttpAttributeRoutes();
- config.Routes.MapHttpRoute(
- name:"DefaultApi",
- routeTemplate:"api/{controller}/{id}",
- defaults:new{id=RouteParameter.Optional}
- );
- }
- }
Web api Controller
- [EnableCors("*","*","*")]
- publicclassGroupListController:ApiController
- {
- privateIGroupService_groupService;
- publicGroupListController(IGroupServicegroupService)
- {
- _groupService=groupService;
- }
- publicIList<GroupBaseDto>GetAll()
- {
- varlist=_groupService.GetAll();
- List<GroupBaseDto>groupList=AutoMapperHelper.MapToList<GroupBaseDto>(list);
- returngroupList;
- }
- publicGroupBaseDtoGetByID(stringid)
- {
- varitem=_groupService.GetByID(id);
- GroupBaseDtogroupdto=AutoMapperHelper.MapTo<GroupBaseDto>(item);
- returngroupdto;
- }
- publicHttpResponseMessagePostGroup(GroupBaseDtogroup)
- {
- try
- {
- group.ID=Guid.NewGuid().ToString();
- TGroupentity=AutoMapperHelper.MapTo<TGroup>(group);
- _groupService.Add(entity);
- returnnewHttpResponseMessage(HttpStatusCode.NoContent);
- }
- catch
- {
- thrownewHttpResponseException(HttpStatusCode.InternalServerError);
- }
- }
- publicHttpResponseMessagePutGroup(stringid,GroupBaseDtogroup)
- {
- try
- {
- group.ID=id;
- TGroupentity=AutoMapperHelper.MapTo<TGroup>(group);
- _groupService.Update(entity);
- returnnewHttpResponseMessage(HttpStatusCode.NoContent);
- }
- catch(Exceptionse)
- {
- thrownewHttpResponseException(HttpStatusCode.InternalServerError);
- }
- }
- publicHttpResponseMessageDeleteGroup(stringid)
- {
- try
- {
- _groupService.Delete(id);
- returnnewHttpResponseMessage(HttpStatusCode.NoContent);
- }
- catch
- {
- thrownewHttpResponseException(HttpStatusCode.InternalServerError);
- }
- }
- }
这里看到通过使用了前面webapi的依赖注入配置,我们在controller的构造函数中就可以使用构造注入Iservice了。这里也可以看到我们的数据传递使用了DTO,一方面是为了效率只传输与业务有关的数据,另一方面业务为了不暴露我们的数据属性。
- publicclassGroupBaseDto
- {
- publicvirtualstringID{get;set;}
- publicvirtualstringGROUPNAME{get;set;}
- publicvirtualdecimal?NORDER{get;set;}
- publicvirtualstringPARENTID{get;set;}
- publicvirtualstringGROUPTYPE{get;set;}
- publicvirtualstringGROUPCODE{get;set;}
- }
为了简单,这个实例我所使用DTO与我所在的领域模型一致,这里还是用了一个AutoMapper工具,Automapper能够让我们在DTO与DO的转换过程更简单了,下面是对AutoMapper的一个封装类,用于处理常用转换。
- ///<summary>
- ///AutoMapper扩展帮助类
- ///</summary>
- publicstaticclassAutoMapperHelper
- {
- ///<summary>
- ///类型映射
- ///</summary>
- publicstaticTMapTo<T>(thisobjectobj)
- {
- if(obj==null)returndefault(T);
- Mapper.Initialize(cfg=>cfg.CreateMap(obj.GetType(),typeof(T)));
- returnMapper.Map<T>(obj);
- }
- ///<summary>
- ///集合列表类型映射
- ///</summary>
- publicstaticList<TDestination>MapToList<TDestination>(thisIEnumerablesource)
- {
- foreach(varfirstinsource)
- {
- vartype=first.GetType();
- Mapper.Initialize(cfg=>cfg.CreateMap(type,typeof(TDestination)));
- break;
- }
- returnMapper.Map<List<TDestination>>(source);
- }
- ///<summary>
- ///集合列表类型映射
- ///</summary>
- publicstaticList<TDestination>MapToList<TSource,TDestination>(thisIEnumerable<TSource>source)
- {
- //IEnumerable<T>类型需要创建元素的映射
- Mapper.Initialize(cfg=>cfg.CreateMap(typeof(TSource),typeof(TDestination)));
- returnMapper.Map<List<TDestination>>(source);
- }
- ///<summary>
- ///类型映射
- ///</summary>
- publicstaticTDestinationMapTo<TSource,TDestination>(thisTSourcesource,TDestinationdestination)
- whereTSource:class
- whereTDestination:class
- {
- if(source==null)returndestination;
- Mapper.Initialize(cfg=>cfg.CreateMap(typeof(TSource),typeof(TDestination)));
- returnMapper.Map(source,destination);
- }
- }
到此我们一个简单的api就已经完成了,可以通过Swashbuckle 进行测试,安装PM> Install-Package Swashbuckle,使用时只需在路径后加入swagger,如http://localhost:6611/swagger/ui/index