Autofac(https://autofac.org/)是一款.NET的IOC組件,它能夠和Owin, Web Api, ASP.NET MVC, .NET Core完美結合,幫助開發人員輕鬆解決程序中的依賴注入問題。html
所謂的動態注入啓動Web Api需求, 就是在Web服務器啓動時, 能夠動態選擇啓動的Web Api 服務。git
之前使用IIS + Web Api的時候,咱們須要手動在IIS中部署全部的Web Api服務,並手動啓動須要使用Web Api服務。github
在微軟推出Owin以後,Owin Self Host + Web Api使開發人員能夠脫離IIS服務器,使用命令行的方式啓動並寄宿一個Web服務。Web服務啓動時,咱們能夠使用一些IOC容器,對Web Api進行動態注入啓動。api
當前有一個項目(源碼:https://github.com/lamondlu/DynamicInjection)中有2個Web Api服務ServiceA, ServiceB, 項目結構以下服務器
Service Aapp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
[RoutePrefix(
"api/ServiceA"
)]
public
class
ServiceAController : ApiController
{
[Route(
"Values"
)]
[HttpGet]
public
List<
string
> Values()
{
return
new
List<
string
> {
"value1"
,
"value2"
};
}
[Route(
"Version"
)]
[HttpGet]
public
string
Version()
{
return
"Service A, version 1.0.0"
;
}
}
|
Service B
測試
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
[RoutePrefix(
"api/ServiceB"
)]
public
class
ServiceBController : ApiController
{
[Route(
"Values"
)]
[HttpGet]
public
List<
string
> Values()
{
return
new
List<
string
> {
"value3"
,
"value4"
};
}
[Route(
"Version"
)]
[HttpGet]
public
string
Version()
{
return
"Service B, version 1.0.0"
;
}
}
|
首先咱們要在DynamicInjection項目添加Owin Self Host庫。ui
在Package Manage Console中輸入如下命令url
Install-Package Microsoft.AspNet.WebApi.OwinSelfHost
spa
而後修改Program.cs代碼,建立一個Startup類,使用Owin Self Host啓動一個Web服務
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
class
Program
{
static
void
Main(
string
[] args)
{
string
baseAddress =
"http://localhost:9002/"
;
using
(WebApp.Start<Startup>(url: baseAddress))
{
Console.WriteLine(
"App Server started."
);
Console.ReadLine();
}
}
public
class
Startup
{
public
void
Configuration(IAppBuilder appBuilder)
{
}
}
}
|
啓動項目,若是出現如下界面,就代表Web服務啓動成功了
程序啓動成功以後,咱們須要繼續修改Program.cs。
首先,咱們須要引入Autofac庫
在Package Manage Console中輸入如下命令
Install-Package Autofac.WebApi2.Owin
引入完成以後,咱們須要在Programs.cs中添加代碼,在啓動服務以前,咱們須要從Services目錄中讀取全部的dll, 使用反射將其加載在內存中,若是發現dll存在繼承自ApiController類的子類時,就將其註冊到當前Web服務中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
public
class
Startup
{
public
void
Configuration(IAppBuilder appBuilder)
{
//定義Autofac容器建立器
var
builder =
new
ContainerBuilder();
//注入Api服務
BuildControllers(builder);
//生成Autofac容器
var
container = builder.Build();
//在Owin管道中加入Autofac中間件
appBuilder.UseAutofacMiddleware(container);
HttpConfiguration config =
new
HttpConfiguration();
config.DependencyResolver =
new
AutofacWebApiDependencyResolver(container);
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name:
"DefaultApi"
,
routeTemplate:
"api/{controller}/{id}"
,
defaults:
new
{ id = RouteParameter.Optional }
);
appBuilder.UseAutofacWebApi(config);
appBuilder.UseWebApi(config);
}
private
void
BuildControllers(ContainerBuilder builder)
{
var
searchFolder = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), SearchPath);
foreach
(
var
file
in
Directory.EnumerateFiles(searchFolder,
"*.dll"
, SearchOption.AllDirectories))
{
try
{
var
assembly = Assembly.LoadFrom(file);
var
exportedTypes = assembly.GetExportedTypes();
if
(exportedTypes.Any(t => t.IsSubclassOf(
typeof
(ApiController))))
{
Console.WriteLine(
"Started service "
+ assembly.FullName);
builder.RegisterApiControllers(assembly).InstancePerRequest();
}
}
catch
{ }
}
}
}
|
啓動項目以後,控制檯結果以下,2個Web Api服務被啓動
而後咱們在Postman中測試一下, Web Api是否能被正確調用