扩展与解耦:Option模式与依赖注入结合
参考 ABP设计UI菜单栏的源码分析,抽出了ABP这块自定义扩展的实现。在ABP的源码里面有很多地方都用到了这种设计方式,实现了用户自定义扩展。
新建一个空的asp.net core项目,新建一个类,源码:
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace DesignPatternSample.Infrastructure
{
public class LanguageInfo
{
public string CultureName { get; set; }
public string DisplayName { get; set; }
public LanguageInfo(string cultureName, string displayName)
{
CultureName = cultureName;
DisplayName = displayName;
}
}
public class AbpSampleOptions
{
public List<LanguageInfo> Languages { get; }
public AbpSampleOptions()
{
Languages = new List<LanguageInfo>();
}
}
public interface ILanguageProvider
{
Task<IReadOnlyList<LanguageInfo>> GetLanguagesAsync();
}
public class DefaultLanguageProvider : ILanguageProvider
{
protected AbpSampleOptions Options { get; }
public DefaultLanguageProvider(IOptions<AbpSampleOptions> options)
{
Options = options.Value;
}
public Task<IReadOnlyList<LanguageInfo>> GetLanguagesAsync()
{
return Task.FromResult((IReadOnlyList<LanguageInfo>)Options.Languages);
}
}
}
StartUp类源码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DesignPatternSample.Infrastructure;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace DesignPatternSample
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
// 依赖注入
services.AddTransient<ILanguageProvider, DefaultLanguageProvider>();
// 配置多语言
services.Configure<AbpSampleOptions>(options =>
{
options.Languages.Add(new LanguageInfo( "cs", "Čeština"));
options.Languages.Add(new LanguageInfo("en", "English"));
options.Languages.Add(new LanguageInfo("pt-BR", "Português"));
options.Languages.Add(new LanguageInfo("tr", "Türkçe"));
options.Languages.Add(new LanguageInfo("zh-Hans", "简体中文"));
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILanguageProvider provider)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
// 测试
endpoints.MapGet("/Abp/Test", async context =>
{
var result = provider.GetLanguagesAsync();
var output = string.Join(",", result.Result.Select(s => s.CultureName).ToArray());
await context.Response.WriteAsync(output);
});
});
}
}
}
扩展点:在ConfigureService
中提供用户自定义扩展点,完美的是下了解耦。
参考: