關於 項目中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  后會發現 兩者會有很多相似之處

最主要還是相當 輕量級  可以高度的自定義   

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM