关于 项目中Ioc基础模块 的搭建 (已适用于.net core / .net Framework / Nancy)

Ioc (Inversion of Control, 控制反转)把创建对象的操作交给框架,亦被称为 DI(Dependency Injection, 依赖注入)。

为什么叫做 “控制反转” 呢?之前,我们想要一个对象都是 new 出来的,天天需要 new 对象是不是感觉有点麻烦。有人就想到了,把这些简单重复的工作也交给框架做。本来需要我们向框架 “射入” 对象,现在框架自己能产生对象了,这不正是 控制反转 吗?于是,就有了这个响亮的名字。

本文不做具体概念讲解 ,项目采用Autofac作为基础框架

  关于Autofac的基础用法可以参照官方的文档教程 很详细  很具体 针对各种版本都有说明  (不要去看各种入门教程 或者翻译文档 全是瞎扯淡) https://autofaccn.readthedocs.io/zh/latest/

 

熟悉Ioc的都应该很清楚  我们常用的操作主要就是两个ResolverRegistrar

Registrar:

  随着项目的逐渐增大,我们基本都采用模块化的方式即 Module  Autofac已经提供了一个基础的Module 我们可以在其内部里面重写Load方法即可,但是考虑以后可能还需要做其他扩展所以我们还是提供一个IRegistrar 接口备用 

参照Load方法 我们只提供一个 ContainerBuilder

protected override void Load(ContainerBuilder builder)

Resolver:

  Autofac已经帮我们实现很多场景下的自动Resolver,但是具体的业务情况却是我们可能需要在自己任意想要的地方去Resolver   所以我们需要自己来实现个IResolver

 1     public interface IResolver
 2     {
 3         /// <summary>
 4         ///     Resolves this instance.
 5         /// </summary>
 6         /// <typeparam name="T"></typeparam>
 7         /// <returns></returns>
 8         T Resolve<T>(ILifetimeScope scope = null);
 9 
10         /// <summary>
11         ///     Determines whether this instance is registered.
12         /// </summary>
13         /// <typeparam name="T"></typeparam>
14         /// <returns>
15         ///     <c>true</c> if this instance is registered; otherwise, <c>false</c>.
16         /// </returns>
17         bool IsRegistered<T>() where T : class;
18 
19         /// <summary>
20         ///     Determines whether the specified type is registered.
21         /// </summary>
22         /// <param name="type">The type.</param>
23         /// <param name="scope">The ILifetimeScope</param>
24         /// <returns>
25         ///     <c>true</c> if the specified type is registered; otherwise, <c>false</c>.
26         /// </returns>
27         bool IsRegistered(Type type, ILifetimeScope scope = null);
28 
29         /// <summary>
30         /// Releases a pre-resolved object. See Resolve methods.
31         /// </summary>
32         /// <param name="obj">Object to be released</param>
33         void Release(object obj);
34 
35         /// <summary>
36         /// Resolve
37         /// </summary>
38         /// <typeparam name="T"></typeparam>
39         /// <param name="parameters"></param>
40         /// <param name="scope"></param>
41         /// <returns></returns>
42         T Resolve<T>(IEnumerable<Parameter> parameters, ILifetimeScope scope = null);
43 
44         /// <summary>
45         /// Resolve
46         /// </summary>
47         /// <typeparam name="T"></typeparam>
48         /// <param name="parameters"></param>
49         /// <returns></returns>
50         T ResolveParameter<T>(params Parameter[] parameters);
51 
52         /// <summary>
53         /// Resolve
54         /// </summary>
55         /// <typeparam name="T"></typeparam>
56         /// <returns></returns>
57         T ResolveName<T>(string name);
58 
59         /// <summary>
60         /// Resolve
61         /// </summary>
62         /// <returns></returns>
63         object Resolve(Type type);
64     }
View Code

 -------------------------------------------------------------------------------------------------------------------------------------

然后 在.net core 中已经内置了Ioc  基本代码如下

1 /// <summary>
2         ///     ConfigureServices
3         /// </summary>
4         /// <param name="services"></param>
5         /// <returns></returns>
6         public IServiceProvider ConfigureServices(IServiceCollection services)
7         {
8         }    
View Code

我们可以知道  .net core 内置的Ioc  是以 IServiceCollection 为核心,所以 如果我们需要支持.net core版本则需要  IServiceCollection   所以我们提供一个 IServiceCollectionResolve

 IServiceCollectionResolve

1     public interface IServiceCollectionResolve
2     {
3         IServiceCollection ServiceCollection { get; set; }
4 
5         T ResolveServiceValue<T>() where T : class, new();
6     }
View Code

Autofac 的核心在于 IContainer 所以我们提供一个 IIocManager 

IIocManager 

 1     public interface IIocManager : IResolver, IRegistrar, IServiceCollectionResolve
 2     {
 3         /// <summary>
 4         ///     Reference to the Autofac Container.
 5         /// </summary>
 6         IContainer IocContainer { get; set; }
 7 
 8         /// <summary>
 9         ///     ServiceLocatorCurrent
10         /// </summary>
11         IServiceLocator ServiceLocatorCurrent { get; set; }
12 
13         /// <summary>
14         ///     SetContainer
15         /// </summary>
16         /// <param name="containerBuilder"></param>
17         void SetContainer(ContainerBuilder containerBuilder);
18 
19         /// <summary>
20         /// SetServiceCollection
21         /// </summary>
22         /// <param name="serviceCollection"></param>
23         void SetServiceCollection(IServiceCollection serviceCollection);
24 
25         /// <summary>
26         /// UpdateContainer
27         /// </summary>
28         /// <param name="containerBuilder"></param>
29         [Obsolete("Containers should generally be considered immutable. Register all of your dependencies before building/resolving. If you need to change the contents of a container, you technically should rebuild the container. This method may be removed in a future major release.")]
30         void UpdateContainer(ContainerBuilder containerBuilder);
31     }
View Code

说明:
IServiceLocator 来源于 CommonServiceLocator  可以在 nuget 找到  可以理解为IResolver  

UpdateContainer 官方已经不推荐使用  可以使用但是尽量避免使用  主要适用场景是 :已经初始化完成后  再需要进行二次注册等操作

 

至此我们所需要的接口基本定义完成。

我们需要一个实现 即 IocManager

  1   /// <summary>
  2     ///     IocManager
  3     /// </summary>
  4     public class IocManager : IIocManager
  5     {
  6         /// <summary>
  7         ///     The Singleton instance.
  8         /// </summary>
  9         public static IocManager Instance { get; }
 10 
 11         #region ContainerBuilder
 12 
 13         /// <summary>
 14         /// ContainerBuilder
 15         /// </summary>
 16         ContainerBuilder IRegistrar.ContainerBuilder
 17         {
 18             get => ContainerBuilder;
 19             set => ContainerBuilder = value;
 20         }
 21 
 22         /// <summary>
 23         ///     ContainerBuilder
 24         /// </summary>
 25         public static ContainerBuilder ContainerBuilder { get; set; }
 26 
 27         #endregion
 28 
 29         #region IContainer
 30 
 31         /// <summary>
 32         ///     IocContainer
 33         /// </summary>
 34         IContainer IIocManager.IocContainer
 35         {
 36             get => IocContainer;
 37             set => IocContainer = value;
 38         }
 39 
 40         /// <summary>
 41         ///     IocContainer
 42         /// </summary>
 43         public static IContainer IocContainer { get; set; }
 44 
 45         #endregion
 46 
 47         #region IServiceLocator
 48 
 49         IServiceLocator IIocManager.ServiceLocatorCurrent
 50         {
 51             get => ServiceLocatorCurrent;
 52             set => ServiceLocatorCurrent = value;
 53         }
 54 
 55         /// <summary>
 56         ///     ServiceLocator
 57         /// </summary>
 58         public static IServiceLocator ServiceLocatorCurrent { get; set; }
 59 
 60         #endregion
 61 
 62         #region IServiceCollection
 63 
 64         IServiceCollection IServiceCollectionResolve.ServiceCollection
 65         {
 66             get => ServiceCollection;
 67             set => ServiceCollection = value;
 68         }
 69 
 70         /// <summary>
 71         ///     ServiceCollection
 72         /// </summary>
 73         public static IServiceCollection ServiceCollection { get; set; }
 74 
 75         #endregion
 76 
 77         /// <summary>
 78         ///     IocManager
 79         /// </summary>
 80         static IocManager()
 81         {
 82             Instance = new IocManager();
 83         }
 84 
 85         /// <summary>
 86         ///     SetContainer
 87         /// </summary>
 88         /// <param name="containerBuilder"></param>
 89         public void SetContainer(ContainerBuilder containerBuilder)
 90         {
 91             ContainerBuilder = containerBuilder;
 92             var container = containerBuilder.Build();
 93             IocContainer = container;
 94 
 95             //设置定位器
 96             ServiceLocatorCurrent = new AutofacServiceLocator(IocContainer);
 97         }
 98 
 99         /// <summary>
100         /// SetServiceCollection
101         /// </summary>
102         /// <param name="serviceCollection"></param>
103         public void SetServiceCollection(IServiceCollection serviceCollection)
104         {
105             ServiceCollection = serviceCollection;
106         }
107 
108         /// <summary>
109         /// UpdateContainer
110         /// </summary>
111         /// <param name="containerBuilder"></param>
112         [Obsolete("Containers should generally be considered immutable. Register all of your dependencies before building/resolving. If you need to change the contents of a container, you technically should rebuild the container. This method may be removed in a future major release.")]
113         public void UpdateContainer(ContainerBuilder containerBuilder)
114         {
115             ContainerBuilder = containerBuilder;
116             containerBuilder?.Update(IocContainer);
117         }
118 
119         /// <summary>
120         ///     resolve T by lifetime scope
121         /// </summary>
122         /// <typeparam name="T"></typeparam>
123         /// <param name="scope"></param>
124         /// <returns></returns>
125         public T Resolve<T>(ILifetimeScope scope = null)
126         {
127             if (scope == null)
128             {
129                 scope = Scope();
130             }
131             return scope.Resolve<T>();
132         }
133 
134         /// <summary>
135         ///     Resolve
136         /// </summary>
137         /// <typeparam name="T"></typeparam>
138         /// <param name="parameters"></param>
139         /// <param name="scope"></param>
140         /// <returns></returns>
141         public T Resolve<T>(IEnumerable<Parameter> parameters, ILifetimeScope scope = null)
142         {
143             if (scope == null)
144             {
145                 scope = Scope();
146             }
147             return scope.Resolve<T>(parameters);
148         }
149 
150         /// <summary>
151         ///     Resolve
152         /// </summary>
153         /// <typeparam name="T"></typeparam>
154         /// <param name="parameters"></param>
155         /// <returns></returns>
156         public T ResolveParameter<T>(Parameter[] parameters)
157         {
158             var scope = Scope();
159             return scope.Resolve<T>(parameters);
160         }
161 
162         /// <summary>
163         /// ResolveName
164         /// </summary>
165         /// <typeparam name="T"></typeparam>
166         /// <returns></returns>
167         public T ResolveName<T>(string name)
168         {
169             var scope = Scope();
170             var item = scope.ResolveNamed<T>(name);
171             return item;
172         }
173 
174         /// <summary>
175         ///
176         /// </summary>
177         /// <param name="type"></param>
178         /// <returns></returns>
179         public object Resolve(Type type)
180         {
181             var scope = Scope();
182             var item = scope.Resolve(type);
183             return item;
184         }
185 
186         /// <summary>
187         ///     IsRegistered
188         /// </summary>
189         /// <typeparam name="T"></typeparam>
190         /// <returns></returns>
191         public bool IsRegistered<T>() where T : class
192         {
193             return IsRegistered(typeof(T));
194         }
195 
196         /// <summary>
197         ///     IsRegistered
198         /// </summary>
199         /// <param name="type"></param>
200         /// <param name="scope"></param>
201         /// <returns></returns>
202         public bool IsRegistered(Type type, ILifetimeScope scope = null)
203         {
204             if (scope == null)
205             {
206                 scope = Scope();
207             }
208 
209             return scope.IsRegistered(type);
210         }
211 
212         /// <summary>
213         ///     release object lifetimescope
214         /// </summary>
215         /// <param name="obj"></param>
216         public void Release(object obj)
217         {
218         }
219 
220         /// <summary>
221         ///     create ILifetimeScope  from container
222         /// </summary>
223         /// <returns></returns>
224         private static ILifetimeScope Scope()
225         {
226             return IocContainer.BeginLifetimeScope();
227         }
228 
229         /// <summary>
230         /// ResolveServiceValue
231         /// </summary>
232         /// <typeparam name="T"></typeparam>
233         /// <returns></returns>
234         public T ResolveServiceValue<T>() where T : class, new()
235         {
236             return ServiceCollection.ResolveServiceValue<T>();
237         }
238     }
View Code

说明:

主要依赖于:

 

这些全部完成后 我们需要一个最终的装载程序  Bootstrap

  1   /// <summary>
  2     ///     初始化装载程序
  3     /// </summary>
  4     public class Bootstrap
  5     {
  6         /// <summary>
  7         ///     _isInit
  8         /// </summary>
  9         private static bool _isInit;
 10 
 11         /// <summary>
 12         ///     _iocManager
 13         /// </summary>
 14         public IIocManager IocManager { get; set; }
 15 
 16         /// <summary>
 17         ///     StartupModule
 18         /// </summary>
 19         public Type StartupModule { get; set; }
 20 
 21         /// <summary>
 22         ///     Instance
 23         /// </summary>
 24         /// <returns></returns>
 25         public static Bootstrap Instance<TStartupModule>() where TStartupModule : WorkDataBaseModule
 26         {
 27             return new Bootstrap(typeof(TStartupModule));
 28         }
 29 
 30         /// <summary>
 31         ///     instance bootstrap
 32         /// </summary>
 33         /// <returns></returns>
 34         public static Bootstrap Instance()
 35         {
 36             return new Bootstrap();
 37         }
 38 
 39         /// <summary>
 40         ///     Bootstrap
 41         /// </summary>
 42         public Bootstrap() : this(Dependency.IocManager.Instance)
 43         {
 44         }
 45 
 46         /// <summary>
 47         ///     Bootstrap
 48         /// </summary>
 49         public Bootstrap(Type startupModule) : this(startupModule, Dependency.IocManager.Instance)
 50         {
 51         }
 52 
 53         /// <summary>
 54         ///     Bootstrap
 55         /// </summary>
 56         /// <param name="iocManager"></param>
 57         public Bootstrap(IIocManager iocManager)
 58         {
 59             IocManager = iocManager;
 60         }
 61 
 62         /// <summary>
 63         ///     Bootstrap
 64         /// </summary>
 65         /// <param name="startupModule"></param>
 66         /// <param name="iocManager"></param>
 67         public Bootstrap(Type startupModule, IIocManager iocManager)
 68         {
 69             StartupModule = startupModule;
 70             IocManager = iocManager;
 71         }
 72 
 73         /// <summary>
 74         ///     初始化集成框架(配置方式)
 75         /// </summary>
 76         [STAThread]
 77         public void InitiateConfig(IServiceCollection services, List<string> paths)
 78         {
 79             if (_isInit) return;
 80             var builder = new ContainerBuilder();
 81 
 82             #region RegisterConfig
 83             var config = new ConfigurationBuilder();
 84             config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory);
 85             if (paths != null)
 86             {
 87                 foreach (var item in paths)
 88                 {
 89                     config.AddJsonFile(item);
 90                 }
 91             }
 92 
 93             var module = new ConfigurationModule(config.Build());
 94             builder.RegisterModule(module);
 95 
 96             #endregion
 97 
 98             //注入初始module
 99             builder.RegisterModule(new WorkDataModule());
100 
101             IocManager.SetServiceCollection(services);
102 
103             builder.Populate(services);
104 
105             IocManager.SetContainer(builder);
106             _isInit = true;
107         }
108 
109         /// <summary>
110         /// InitiateConfig
111         /// </summary>
112         /// <param name="paths"></param>
113         public void InitiateConfig(List<string> paths)
114         {
115             if (_isInit) return;
116             var builder = new ContainerBuilder();
117 
118             #region RegisterConfig
119             var config = new ConfigurationBuilder();
120             config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory);
121             if (paths != null)
122             {
123                 foreach (var item in paths)
124                 {
125                     config.AddJsonFile(item);
126                 }
127             }
128 
129             var module = new ConfigurationModule(config.Build());
130             builder.RegisterModule(module);
131 
132             #endregion
133 
134             //注入初始module
135             builder.RegisterModule(new WorkDataModule());
136 
137             IocManager.SetContainer(builder);
138             _isInit = true;
139         }
140 
141         /// <summary>
142         /// UpdateContainer
143         /// </summary>
144         /// <param name="services"></param>
145         [Obsolete("Containers should generally be considered immutable. Register all of your dependencies before building/resolving. If you need to change the contents of a container, you technically should rebuild the container. This method may be removed in a future major release.")]
146         public void CoreUpdateContainer(IServiceCollection services)
147         {
148             var builder = new ContainerBuilder();
149             builder.Populate(services);
150             IocManager.UpdateContainer(builder);
151         }
152 
153        
154     }
View Code

 

这样我们整体的架子就算初步完成了  

扩展

1.随着项目逐渐增大 我们会有很多很多的接口  去进行注入  我们  希望通过反射的方式进行注入  所以我们提供一个 ITypeFinder 方便进行操作

注:  ITypeFinder  来源于 nopcommerce

代码位置 :

https://github.com/wulaiwei/WorkData.Core/tree/master/WorkData/WorkData/Extensions/TypeFinders

2. 在 .net Framework  autofac 针对常量的配置 我们可以采用属性注入的方式完成  ,但是针对.net core版本 不推荐采用 属性注入  ,推荐使用core 自带的文件注入方式

1         public Startup(IHostingEnvironment env)
2         {
3             var builder = new ConfigurationBuilder()
4                 .SetBasePath(env.ContentRootPath)
5                 .AddJsonFile("Config/appsettings.json", optional: true, reloadOnChange: true)
6                 .AddJsonFile($"Config/appsettings.{env.EnvironmentName}.json", optional: true)
7                 .AddEnvironmentVariables();
8             this.Configuration = builder.Build();
9         }
View Code

有个参数选项  为 reloadOnChange: true  即修改后会自动重新加载 ,然后注入至 IServiceCollection既可以

我们可以采用IocManager 进行 Resolve 但是你就立马会遇到很尴尬的问题  加入我还没注入完成 我就需要这个对象呢   

例如  加入我需要使用JWT

 1  services.AddAuthentication(options =>
 2                 {
 3                     //认证middleware配置
 4                     options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
 5                     options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
 6                 })
 7                 .AddJwtBearer(o =>
 8                 {
 9                     //主要是jwt  token参数设置
10                     o.TokenValidationParameters = new TokenValidationParameters
11                     {
12                         //Token颁发机构
13                         ValidIssuer = workDataBaseJwt.Issuer,
14                         //颁发给谁
15                         ValidAudience = workDataBaseJwt.Audience,
16                         //这里的key要进行加密,需要引用Microsoft.IdentityModel.Tokens
17                         IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(workDataBaseJwt.SecretKey)),
18                         //ValidateIssuerSigningKey=true,
19                         ////是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比
20                         ValidateLifetime = true,
21                         ////允许的服务器时间偏移量
22                         ClockSkew = TimeSpan.Zero
23                     };
24                 });
View Code

然后就需要这个对象 workDataBaseJwt  所以  我们这边需要对 IServiceCollection  做个扩展

 1 public static class WorkDataServiceCollection
 2     {
 3         public static T ResolveServiceValue<T>(this IServiceCollection services) where T : class, new()
 4         {
 5             try
 6             {
 7                 var provider = services.BuildServiceProvider();
 8                 var entity = provider.GetRequiredService<IOptions<T>>().Value;
 9                 return entity;
10             }
11             catch (Exception)
12             {
13                 return default(T);
14             }
15         }
16     }
View Code

这样我就可以在注入之前进行Resolve    即:

1     services.Configure<WorkDataBaseJwt>(Configuration.GetSection("WorkDataBaseJwt"));
2             services.Configure<WorkDataDbConfig>(Configuration.GetSection("WorkDataDbContextConfig"));
3             services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
4             services.AddTransient<IPrincipal>(provider =>
5             provider.GetService<IHttpContextAccessor>().HttpContext.User);
6             
7             var workDataBaseJwt = services.ResolveServiceValue<WorkDataBaseJwt>();
View Code

最后推荐使用   json  进行模块注册

 1 {
 2   "modules": [
 3     {
 4       "type": "WorkData.Web.WorkDataWebModule,WorkData.Web"
 5     },
 6     {
 7       "type": "WorkData.Domain.EntityFramework.DomainEntityFrameworkModule,WorkData.Domain.EntityFramework"
 8     },
 9     {
10       "type": "WorkData.EntityFramework.EntityFrameworkModule,WorkData.EntityFramework"
11     },
12     {
13       "type": "WorkData.Code.WorkDataCodeModule,WorkData.Code"
14     }
15   ]
16 }
View Code

关于在.net core 版本下的完整使用  可以参考  :

https://github.com/wulaiwei/WorkData.Core/tree/master/WorkData/WorkData.Web

 最后针对Nancy   WorkData的使用 

主要依赖于

using Autofac;
using Nancy;
using Nancy.Bootstrapper;
using Nancy.Bootstrappers.Autofac;

  1     public class WorkDataAutofacNancyBootstrapper : AutofacNancyBootstrapper
  2     {
  3         /// <summary>
  4         ///     Gets a reference to the <see cref="Bootstrap" /> instance.
  5         /// </summary>
  6         public static Bootstrap BootstrapWarpper { get; } = Bootstrap.Instance();
  7 
  8         private readonly ILogService _logService;
  9 
 10         static WorkDataAutofacNancyBootstrapper()
 11         {
 12             BootstrapWarpper.InitiateConfig();
 13         }
 14 
 15         public WorkDataAutofacNancyBootstrapper()
 16         {
 17             _logService = BootstrapWarpper.IocManager.Resolve<ILogService>();
 18         }
 19 
 20         protected override ILifetimeScope GetApplicationContainer()
 21         {
 22             return BootstrapWarpper.IocManager.IocContainer;
 23         }
 24 
 25         protected override void ConfigureApplicationContainer(ILifetimeScope container)
 26         {
 27             var builder = new ContainerBuilder();
 28             builder.RegisterType<CustomJsonNetSerializer>().As<ISerializer>();
 29             builder.RegisterType<UserMapper>().As<IUserMapper>();
 30 
 31             BootstrapWarpper.IocManager.UpdateContainer(builder);
 32         }
 33 
 34         protected override void RequestStartup(ILifetimeScope container, IPipelines pipelines, NancyContext context)
 35         {
 36             base.RequestStartup(container, pipelines, context);
 37 
 38             #region 拦截器
 39 
 40             pipelines.BeforeRequest += ctx =>
 41             {
 42                 var logRequest = new LogRequest
 43                 {
 44                     Url = context.Request.Url,
 45                     Form = JsonConvert.SerializeObject(context.Request.Form),
 46                     Query = JsonConvert.SerializeObject(context.Request.Query),
 47                     Method = context.Request.Method,
 48                     Body = context.Request.Body.AsString(),
 49                     Key = Guid.NewGuid().ToString(),
 50                     CreateTime = DateTime.Now,
 51                     CreateUserId = ctx.GetUserIdentity()?.UserId
 52                 };
 53                 _logService.AddRequestIndex(logRequest);
 54                 return null;
 55             };
 56             pipelines.AfterRequest += ctx => { };
 57             pipelines.OnError += (ctx, ex) =>
 58             {
 59                 var logRequestError = new LogRequestError
 60                 {
 61                     Url = context.Request.Url,
 62                     ErrorMessage = ex.Message,
 63                     Key = Guid.NewGuid().ToString(),
 64                     CreateTime=DateTime.Now,
 65                     CreateUserId= ctx.GetUserIdentity()?.UserId
 66                 };
 67                 _logService.AddRequestErrorIndex(logRequestError);
 68 
 69                 return null;
 70             };
 71 
 72             #endregion
 73         }
 74 
 75         protected override void ApplicationStartup(ILifetimeScope container, IPipelines pipelines)
 76         {
 77             base.ApplicationStartup(container, pipelines);
 78             DiagnosticsHook.Disable(pipelines);
 79 
 80             pipelines.AfterRequest += ctx =>
 81             {
 82                 ctx.Response.Headers.Add("Access-Control-Allow-Origin", "*");
 83                 ctx.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
 84                 ctx.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET");
 85                 ctx.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type,Access-Token");
 86                 ctx.Response.Headers.Add("Access-Control-Expose-Headers", "*");
 87             };
 88            
 89             #region Authentication
 90             var configuration = new StatelessAuthenticationConfiguration(
 91                 nancyContext =>
 92                 {
 93                     //返回null代码token无效或用户未认证
 94                     var token = nancyContext.Request.Headers.Authorization;
 95                     if (string.IsNullOrEmpty(token))
 96                         return null;
 97                     var userValidator = BootstrapWarpper.IocManager.Resolve<IUserMapper>();
 98 
 99                     var userIdentity = userValidator.GetUserFromAccessToken(token);
100 
101                     return userIdentity;
102                 }
103             );
104             StatelessAuthentication.Enable(pipelines, configuration);
105             #endregion
106 
107             //启用Session
108             //CookieBasedSessions.Enable(pipelines);
109 
110             base.ApplicationStartup(container, pipelines);
111         }
112 
113         /// <summary>
114         ///     RootPathProvider
115         /// </summary>
116         protected override IRootPathProvider RootPathProvider =>
117             new WorkDataRootPathProvider();
118 
119         /// <summary>
120         ///     配置静态文件访问权限
121         /// </summary>
122         /// <param name="conventions"></param>
123         protected override void ConfigureConventions(NancyConventions conventions)
124         {
125             base.ConfigureConventions(conventions);
126 
127             //静态文件夹访问 设置 css,js,image
128             conventions.StaticContentsConventions.AddDirectory("Contents");
129         }
130     }
View Code

推荐 下Nancy    虽然 有.net  core 但是  如果你用Nancy  后会发现 两者会有很多相似之处

最主要还是相当 轻量级  可以高度的自定义   

 

posted @ 2018-08-01 15:46  飘渺丶散人  阅读(1366)  评论(0编辑  收藏  举报