Skip to content

Commit

Permalink
add readme_zh-CN.md sample
Browse files Browse the repository at this point in the history
  • Loading branch information
SENewJax committed Aug 26, 2021
1 parent daa29ce commit c40ad2f
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 12 deletions.
107 changes: 105 additions & 2 deletions README_zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,109 @@ public void ConfigureServices(IServiceCollection services)
...

(9)`[DynamicWebApi]` 特性因为可被继承,所以为了父类被误识别,禁止放在除抽象类、接口以外的父类上。
(10)自定义 WebApi注册
### 1.基础功能
```csharp
public void ConfigureServices(IServiceCollection services)
{
// 自定义配置
services.AddDynamicWebApi((options) =>
{
//自定义注册的WebApi
options.SelectController = new ServiceLocalSelectController();
//自定义WebApi路由地址
options.ActionRouteFactory = new ServiceActionRouteFactory();
});
}
```

根据 ServiceAttribute 注册WebApi和分配路由地址
```csharp
[AttributeUsage(AttributeTargets.Class)]
public class ServiceAttribute : Attribute
{
public ServiceAttribute()
{
ServiceName = string.Empty;
}

public ServiceAttribute(string serviceName)
{
ServiceName = serviceName;
}

public string ServiceName { get; }
}
```

实现 ISelectController 接口,通过查找类是否有ServiceAttribute特性为注册WebApi条件
```csharp
internal class ServiceLocalSelectController : ISelectController
{
public bool IsController(Type type)
{
return type.IsPublic && type.GetCustomAttribute<ServiceAttribute>() != null;
}
}
```

实现 IActionRouteFactory 接口,生成路由规则 /api/ServiceName/Method
```csharp
internal class ServiceActionRouteFactory : IActionRouteFactory
{
public string CreateActionRouteModel(string areaName, string controllerName, ActionModel action)
{
var controllerType = action.ActionMethod.DeclaringType;
var serviceAttribute = controllerType.GetCustomAttribute<ServiceAttribute>();

var _controllerName = serviceAttribute.ServiceName == string.Empty ? controllerName.Replace("Service", "") : serviceAttribute.ServiceName.Replace("Service", "");

return $"api/{_controllerName}/{action.ActionName.Replace("Async", "")}";
}
}
```
ServiceAttribute.ServiceName为空时,controllerName 替换 "Service" 字符串为空,反之则 ServiceAttribute.ServiceName 替换 "Service" 字符串为空。
Method 名替换 "Async" 字符串为空。

### 2.外部动态 WebApi
创建一个 Other.Controller
实现 一个外部 Service
```csharp
[Service("Other.Server")]
public class OtherService
{
public int Show()
{
return 100;
}

public Task<int> TaskIntAsync()
{
return Task.FromResult(100);
}
}
```

```csharp
public void ConfigureServices(IServiceCollection services)
{
// 自定义配置
services.AddDynamicWebApiCore<ServiceLocalSelectController, ServiceActionRouteFactory>();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseDynamicWebApi((serviceProvider,options) =>
{
options.AddAssemblyOptions(typeof(OtherService).Assembly);
});
}
```

## 3.配置

Expand All @@ -183,8 +286,8 @@ public void ConfigureServices(IServiceCollection services)
| DefaultHttpVerb || 默认值:POST。默认HTTP动词 |
| DefaultAreaName || 默认值:空。Area 路由名称 |
| DefaultApiPrefix || 默认值:api。API路由前缀 |
| RemoveControllerPostfixes || 默认值:AppService/ApplicationService。类名需要移除的后缀 |
| RemoveActionPostfixes || 默认值:Async。方法名需要移除的后缀 |
| RemoveControllerPostfixes || 默认值:AppService/ApplicationService。类名需要移除的后缀 |
| RemoveActionPostfixes || 默认值:Async。方法名需要移除的后缀 |
| FormBodyBindingIgnoredTypes || 默认值:IFormFile。不通过MVC绑定到参数列表的类型。 |

## 4.疑难解答
Expand Down
4 changes: 1 addition & 3 deletions samples/Panda.DynamicWebApiSample/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public void ConfigureServices(IServiceCollection services)
// options.AddAssemblyOptions(this.GetType().Assembly, apiPreFix: "apis", httpVerb: "POST");
//});


services.AddDynamicWebApiCore<ServiceLocalSelectController, ServiceActionRouteFactory>();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
Expand All @@ -105,8 +105,6 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
app.UseDynamicWebApi((serviceProvider,options) =>
{
options.AddAssemblyOptions(typeof(OtherService).Assembly);
options.SelectController = new ServiceLocalSelectController();
options.ActionRouteFactory = new ServiceActionRouteFactory();
});

app.UseRouting();
Expand Down
22 changes: 15 additions & 7 deletions src/Panda.DynamicWebApi/DynamicWebApiServiceExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,9 @@ public static IApplicationBuilder UseDynamicWebApi(this IApplicationBuilder appl

var partManager = application.ApplicationServices.GetRequiredService<ApplicationPartManager>();

if (partManager == null)
{
throw new InvalidOperationException("\"UseDynamicWebApi\" must be after \"AddMvc\".");
}

// Add a custom controller checker
partManager.FeatureProviders.Add(new DynamicWebApiControllerFeatureProvider(options.SelectController));
var featureProviders = application.ApplicationServices.GetRequiredService<DynamicWebApiControllerFeatureProvider>();
partManager.FeatureProviders.Add(featureProviders);

foreach(var assembly in options.AssemblyDynamicWebApiOptions.Keys)
{
Expand All @@ -61,12 +57,24 @@ public static IApplicationBuilder UseDynamicWebApi(this IApplicationBuilder appl


var mvcOptions = application.ApplicationServices.GetRequiredService<IOptions<MvcOptions>>();
var dynamicWebApiConvention = application.ApplicationServices.GetRequiredService<DynamicWebApiConvention>();

mvcOptions.Value.Conventions.Add(new DynamicWebApiConvention(options.SelectController, options.ActionRouteFactory));
mvcOptions.Value.Conventions.Add(dynamicWebApiConvention);

return application;
}

public static IServiceCollection AddDynamicWebApiCore<TSelectController, TActionRouteFactory>(this IServiceCollection services)
where TSelectController: class,ISelectController
where TActionRouteFactory: class, IActionRouteFactory
{
services.AddSingleton<ISelectController, TSelectController>();
services.AddSingleton<IActionRouteFactory, TActionRouteFactory>();
services.AddSingleton<DynamicWebApiConvention>();
services.AddSingleton<DynamicWebApiControllerFeatureProvider>();
return services;
}

/// <summary>
/// Add Dynamic WebApi to Container
/// </summary>
Expand Down

0 comments on commit c40ad2f

Please sign in to comment.