动态注册区域和控制器

时间:2018-06-25 13:38:21

标签: c# asp.net-core

我有一个模块化的Web应用程序,我需要在运行时加载一些库,这些库将包含Controllers

每个控制器必须只有一个Area,并且对于该库中的所有控制器都是通用的。

Example1

我已经使用ASP.NET Core的应用程序部件在运行时加载此程序集。

services.AddMvcCore(setup =>
{
    setup.Filters.Add(new AuthorizeFilter());

    // Get all global filters
    foreach (var filter in GetInterfacesFromAssembly<IGlobalAsyncFilter>())
        setup.Filters.Add(new AsyncActionFilterProxy(filter, container));
})
.SetCompatibilityVersion(CompatibilityVersion.Latest)
.AddFormatterMappings()
.AddJsonFormatters()
.AddCors()
.AddAuthorization(o =>
{
    o.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme)
     .RequireAuthenticatedUser()
     .Build();
})
.AddApplicationPart(GetModuleAssemblies());

GetModuleAssemblies获取在运行时中可能包含Controllers

的所有可能的库
/// <summary>
/// Get any DLL that contains "ModularPortal.Modules.*.dll"
/// </summary>
private static IEnumerable<Assembly> GetModuleAssemblies()
{
    string location = Assembly.GetEntryAssembly().Location;
    string path = Path.GetDirectoryName(location);
    DirectoryInfo directory = new DirectoryInfo(path);

    FileInfo[] files = directory.GetFiles("ModularPortal.Module*.dll");
    foreach (FileInfo file in files)
        yield return Assembly.Load(file.Name.Replace(".dll", ""));
}

使用此命令,以下控制器位于/api/example1/test中:

[AllowAnonymous]
public class Example1Controller : ControllerBase
{
    readonly IMembership membership;

    public Example1Controller(
            IMembership membership
        )
    {
        this.membership = membership;
    }

    [HttpGet]
    public IActionResult Test()
    {
        return Ok("t1");
    }
}

问题在于,通过添加ApplicationPart,我需要使用AreaAttribute来识别控制器属于/Area的身份。

我想要一个通用的“模块配置器”,该库中的任何控制器都将具有一个公共区域。

我首先创建一个用于标识模块的接口:

public interface IModule
{
    string DisplayName { get; }
    string RouteName { get; }

    void Configure(ModuleConfiguration config);
}

然后在库中,我使用了它:

public class Module : IModule
{
    public string DisplayName => "Example Module";

    public string RouteName => "Ex";

    public void Configure(ModuleConfiguration config)
    {
        throw new NotImplementedException();
    }
}

我想使用此代码来配置有关该模块的所有内容,包括区域和控制器注册。

在上面的示例中,注册区域后,路径应为/api/ex1/example1/test

这只有在我以某种方式更改了AddApplicationPart以自己注册的情况下才能实现。

有什么主意吗?

1 个答案:

答案 0 :(得分:1)

好像您正在尝试构建模块化项目一样。这是给您的参考文献link

希望对您有所帮助,如果您有任何疑问,请告诉我。我很乐意支持。