.net MVC, webAPI,webForm集成steeltoe+springcloud实现调用服务中心服务的总结

时间:2022-08-27 14:24:01

开始之前,如果没接触过Autofac的,可以移步到Autofac官方示例学习一下怎么使用:https://github.com/autofac/Examples

.net 下集成steeltoe进行微服务客户端的注册与发现均需要使用Autofac依赖注入方式进行,且MVC,WebAPI,webForm三种项目类型所需要依赖扩展库都不一样,经过两周的踩坑,现在做个粗浅的总结吧!

以下是steeltoe官方文档给出的参考:

App Type Package Description
Console/ASP.NET 4.x Steeltoe.Discovery.EurekaBase Base functionality. No dependency injection.
ASP.NET Core Steeltoe.Discovery.ClientCore Includes base. Adds ASP.NET Core dependency injection.
ASP.NET 4.x with Autofac Steeltoe.Discovery.ClientAutofac Includes base. Adds Autofac dependency injection.
App Type Package Description
Console/ASP.NET 4.x Pivotal.Discovery.EurekaBase Base functionality. No dependency injection.
ASP.NET Core Pivotal.Discovery.ClientCore Includes base. Adds ASP.NET Core dependency injection.
ASP.NET 4.x with Autofac Pivotal.Discovery.ClientAutofac Includes base. Adds Autofac dependency injection.

经过两周的各自尝试,基于Framework4.5.2+的MVC,WebAPI,webForm等项目基本都是用Autofac方式进行服务注册和调用方法的引用,所以所需要引入的扩展库基本都是以Autofac结尾,比如上面的Steeltoe.Discovery.ClientAutofac和Pivotal.Discovery.ClientAutofac。

另外我们还需要用到的类库包括:

Steeltoe.Common.Autofac

这个类库包含了服务发现与调用的方法。

三种类型的项目目录结构是不同的,MVC与WebAPI都是有ApiController接口的,可以自己构建controller集成接口,然后直接用Autofac的依赖注入方式进行微服务调用方法的实现,代码可参考如下:

 public class ValuesController : ApiController
{
private readonly DiscoveryHttpClientHandler _handler; public ValuesController(IDiscoveryClient client, ILoggerFactory logFactory)//这里就是注入依赖了
{
_handler = new DiscoveryHttpClientHandler(client);
} // GET api/values
public async Task<string> Get()
{ var client = new HttpClient(_handler, false); return await client.GetStringAsync("http://java-server/hi?name=demo");
} // GET api/values/5
public string Get(int id)
{
String re = id.ToString; return re; } // POST api/values
public void Post([FromBody]string value)
{
} // PUT api/values/5
public void Put(int id, [FromBody]string value)
{
} // DELETE api/values/5
public void Delete(int id)
{
}
}

  

那么webForm怎么调用微服务的方法呢?这就需要我们自己写一个服务类,在类中实现自定义接口和用依赖注入的方式对steeltoe提供的方法调用,然后在Page里依赖注入自己的这个类了。参考代码:

自定义服务接口类IFetchService.cs:

 public interface IFetchService
{
Task<string> RandomFortuneAsync();
}

自定义服务类并完成steeltoe接口方法的依赖注入与实现FetchService.cs:

public class FetchService : IFetchService
{
DiscoveryHttpClientHandler _handler; private const string RANDOM_FORTUNE_URL = "http://java-service/hi?name=tian";
private ILogger<FetchService> _logger; public FetchService(IDiscoveryClient client, ILoggerFactory logFactory = null)
{
_handler = new DiscoveryHttpClientHandler(client);
_logger = logFactory?.CreateLogger<FetchServise>();
} public async Task<string> RandomFortuneAsync()
{
_logger?.LogInformation("RandomFortuneAsync");
var client = GetClient();
return await client.GetStringAsync(RANDOM_FORTUNE_URL); } private HttpClient GetClient()
{
var client = new HttpClient(_handler, false);
return client;
}
}

接下来,最重要的步骤,在程序全局文件Global.asax中进行依赖注入的配置,这里引用到的Autofac扩展库也是有区别:

MVC直接引用Autofac即可

WebAPI引用的是Autofac.WebApi2

webForm引用的是Autofac.Web

这里主要写下 webForm的配置代码:

 public class Global : System.Web.HttpApplication, IContainerProviderAccessor
{
// 持有应用程序容器的提供程序
static IContainerProvider _containerProvider; //将被`Autofac HttpModules`用来解析和注入依赖关系的实例属性。
public IContainerProvider ContainerProvider
{
get { return _containerProvider; }
} protected void Application_Start(object sender, EventArgs e)
{
ApplicationConfig.RegisterConfig("development");
//var config = GlobalConfiguration.Configuration;
var builder = new ContainerBuilder(); // Add Microsoft Options to container
builder.RegisterOptions(); // Add Microsoft Logging to container
builder.RegisterLogging(ApplicationConfig.Configuration); // Add Console logger to container
builder.RegisterConsoleLogging(); //// Register all the controllers with Autofac
builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly()); // Register IDiscoveryClient, etc.
builder.RegisterDiscoveryClient(ApplicationConfig.Configuration); // Register FortuneService builder.RegisterType<FetchServise>().As<IFetchServise>();//MVC,webAPI也是这么写 // Create the Autofac container
var container = builder.Build(); _containerProvider = new ContainerProvider(container); //config.DependencyResolver = new AutofacWebApiDependencyResolver(container);//WebAPI创建容器
//DependencyResolver.SetResolver(new AutofacDependencyResolver(container));//MVC创建容器 container.StartDiscoveryClient(); } protected void Session_Start(object sender, EventArgs e)
{ } protected void Application_BeginRequest(object sender, EventArgs e)
{ } protected void Application_AuthenticateRequest(object sender, EventArgs e)
{ } protected void Application_Error(object sender, EventArgs e)
{ } protected void Session_End(object sender, EventArgs e)
{ } protected void Application_End(object sender, EventArgs e)
{ }
}

  

 然后在Page代码页中依赖注入实现我们自定义的接口方法:

 public partial class WebForm2 : System.Web.UI.Page
{
public IFetchServise fetch { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
this.Page.RegisterAsyncTask(new PageAsyncTask(GetName));
} private async Task GetName()
{
Label1.Text = await fetch.RandomFortuneAsync();
}
}