Autofac 使用接口自动进行程序集扫描 - .net core 3.0 - 根据生命周期注册

2023-12-14

我意识到这个问题被问了很多。但我无法找出这个问题的解决方案。

我试图解决的问题是创建三个单独的接口(Singleton Scoped、InstancePerRequest)。 并将所有服务注册到其实现的接口下,而无需手动将它们添加到 DI 容器中。

适用于某些类别类型的 Autofac 扫描组件

Autofac 注册程序集类型

Autofac 程序集扫描 - .NET Core

在你说重复之前听我说完。

我已经为所提出的问题提供了解决方案。但我想搜索整个解决方案,而不是局限于一个项目。我已在服务项目中添加了 autofac 模块,以便它注册服务项目中存在的内容。请参见answer为了更好地理解下面的内容。

我尝试实现多项目扫描,请参阅下面的代码。这是行不通的。

这是我的 Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseServiceProviderFactory(new AutofacServiceProviderFactory())
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

这是我的启动类中的配置容器。我忽略了所有其他项目,因为这只是一个新的 ASP.NET Core 项目。

public void ConfigureContainer(ContainerBuilder builder)
    {
        //builder.RegisterType<EpisodeServices>().As<IEpisodeService>().InstancePerLifetimeScope(); This works

        var executingDirectory = AppDomain.CurrentDomain.BaseDirectory;
        //The sth is my Solution's header for example Sth.Core, Sth.Models, Sth.Services all are childs to the Sth Solution
        string[] files = Directory.GetFiles(executingDirectory, "Sth.*.dll", SearchOption.AllDirectories);
        var listOfAssemblies = new List<Assembly>();
        foreach (var file in files)
            listOfAssemblies.Add(Assembly.LoadFile(file));

        builder
            .RegisterAssemblyTypes(listOfAssemblies.ToArray())
            .Where(t => t.GetInterfaces().Any(i => i.IsAssignableFrom(typeof(ISthScopedService))))
            .AsImplementedInterfaces()
            .InstancePerLifetimeScope();
    }

到目前为止,一切都很好。

这是一个示例服务,以便您可以充分了解我的实现。

public class EpisodeServices : IEpisodeService
{
    public IList<Episode> GetEpisodes()
    {
        return new List<Episode>
        {
            new Episode { Id = 1, Name = "Some Name", Description = "Some Description" }
        };
    }
}

这是界面:

public interface IEpisodeService : ISthScopedService
{
    IList<Episode> GetEpisodes();

}

这是控制器的注入

public class EpisodeController : Controller
{
    private readonly IEpisodeService _episodeService;

    public EpisodeController(IEpisodeService episodeService)
    {
        _episodeService = episodeService;
    }
    public IActionResult Index()
    {
        var data = _episodeService.GetEpisodes();
        return Content(data[0].Name);
    }
}

如果我像这样运行我会得到Invalid Operation Exception: Unable to resolve service for type namespace.IEpisodeService尝试激活时EpisodeController.

有人可以提供更多关于如何实现这一目标的实施细节吗?


提供的解决方案无法解决解决方案扫描问题。但它使用程序集扫描。您也可以将其视为如何实现此目标的分步指南。我们的解决方案看起来像这样。

Sth.Core --> Class Library.

Sth.Services --> Class Library(Assembly scanning will happen here).

Sth.Web --> ASP.NET Core MVC project.

The Sth.Core has our three-lifetime interfaces which our Services need to inherit from.
 - ISthInstanceService
 - ISthScopedService
 - ISthSingletonService

Sth.Web.Program.cs

public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseServiceProviderFactory(new AutofacServiceProviderFactory()) //Add this
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }

Sth.Web,Startup.cs

public void ConfigureContainer(ContainerBuilder builder)
        {
            builder.RegisterModule(new SthModule()); // This is the autofac Module. We add it later at the Services Project
        }

现在我们的服务项目。在这里我们需要创建 autofac 模块。实例化的一个 asp.net 应用程序。

public class SthModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        
        var assemblies = AppDomain.CurrentDomain.GetAssemblies();
        builder
            .RegisterAssemblyTypes(assemblies)
            .Where(t => t.GetInterfaces().Any(i => i.IsAssignableFrom(typeof(ISthScopedService))))
            .AsImplementedInterfaces()
            .InstancePerLifetimeScope(); // Add similar for the other two lifetimes
        base.Load(builder);
    }
}

上面的代码将扫描所有Services项目并添加所有继承自ISthScopedService的类并将它们注册到容器中。

Sth.Service.EpisodeService.cs

 public class EpisodeServices : IEpisodeService
{
    public IList<Episode> GetEpisodes()
    {
        return new List<Episode>
        {
            new Episode { Id = 1, Name = "Imposter Syndrome", Description = "Imposter syndrome" }
        };
    }
}

还有界面。

public interface IEpisodeService : ISthCommonService
    {
        IList<Episode> GetEpisodes();
    }

现在我们已经为我们的服务项目实现了程序集扫描(自动注册)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Autofac 使用接口自动进行程序集扫描 - .net core 3.0 - 根据生命周期注册 的相关文章

  • 是否需要销毁运算符删除的形式才能真正销毁对象?

    C 20 添加了破坏形式operator delete区别于std destroying delete t范围 它导致delete表达式在调用之前不再销毁对象operator delete 目的是在显式调用对象的析构函数和释放内存之前 允许
  • C# 中的 Stack<> 实现

    我最近一直在实现递归目录搜索实现 并且使用堆栈来跟踪路径元素 当我使用 string Join 连接路径元素时 我发现它们被颠倒了 当我调试该方法时 我查看了堆栈 发现堆栈内部数组中的元素本身是相反的 即最近 Push 的元素位于内部数组的
  • 在 C 语言中,为什么数组的地址等于它的值?

    在下面的代码中 指针值和指针地址与预期不同 但数组值和地址则不然 怎么会这样 Output my array 0022FF00 my array 0022FF00 pointer to array 0022FF00 pointer to a
  • 在 Mono 中反序列化 JSON 数据

    使用 Monodroid 时 是否有一种简单的方法可以将简单的 JSON 字符串反序列化为 NET 对象 System Json 只提供序列化 不提供反序列化 我尝试过的各种第三方库都会导致 Mono Monodroid 出现问题 谢谢 f
  • 防止控制台应用程序中的内存工作集最小化?

    我想防止控制台应用程序中的内存工作集最小化 在Windows应用程序中 我可以这样做覆盖 SC MINIMIZE 消息 http support microsoft com kb 293215 en us fr 1 但是 如何在控制台应用程
  • 为什么这个 makefile 在“make clean”上执行目标

    这是我当前的 makefile CXX g CXXFLAGS Wall O3 LDFLAGS TARGET testcpp SRCS main cpp object cpp foo cpp OBJS SRCS cpp o DEPS SRCS
  • OpenGL:如何检查用户是否支持glGenBuffers()?

    我检查了文档 它说 OpenGL 版本必须至少为 1 5 才能制作glGenBuffers 工作 用户使用的是1 5版本但是函数调用会导致崩溃 这是文档中的错误 还是用户的驱动程序问题 我正在用这个glGenBuffers 对于VBO 我如
  • Linux 上的 RTLD_LOCAL 和dynamic_cast

    我们有一个由应用程序中的一些共享库构成的插件 我们需要在应用程序运行时更新它 出于性能原因 我们在卸载旧插件之前加载并开始使用新插件 并且只有当所有线程都使用旧插件完成后 我们才卸载它 由于新插件和旧插件的库具有相同的符号 我们dlopen
  • 来自嵌入图像的 BitmapSource

    我的目标是在 WPF 窗口上重写 OnRender 方法中绘制图像 someImage png 它是嵌入资源 protected override void OnRender System Windows Media DrawingCont
  • 保证复制省略是否适用于函数参数?

    如果我理解正确的话 从 C 17 开始 这段代码现在要求不进行任何复制 Foo myfunc void return Foo auto foo myfunc no copy 函数参数也是如此吗 下面的代码中的副本会被优化掉吗 Foo myf
  • C# 获取数据表中所有重复行的计数

    我通过运行存储过程来填充数据集 并且从数据集中填充数据表 DataSet RawDataSet DataAccessHelper RunProcedure storedprocedureName this will just return
  • wordexp 失败时我们需要调用 wordfree 吗?

    wordexp 失败时我们需要调用 wordfree 吗 在某些情况下 调用 wordfree 似乎会出现段错误 例如 当 wordfree 返回字符串为 foo bar 的错误代码时 这在手册页中并不清楚 我已经看到在某些错误情况下使用了
  • 在 azure blob 存储中就地创建 zip 文件

    我将文件存储在 Blob 存储帐户内的一个容器中 我需要在第二个容器中创建一个 zip 文件 其中包含第一个容器中的文件 我有一个使用辅助角色和 DotNetZip 工作的解决方案 但由于 zip 文件的大小最终可能达到 1GB 我担心在进
  • 如何从 Boost.PropertyTree 复制子树

    我有一些boost property tree ptree 我需要树来删除一些具有特定标签名称的元素 例如 xml 表示源ptree如下
  • 在哪里可以找到 Microsoft.Build.Utilities.v3.5

    如何获取 Microsoft Build Utilities v3 5 我正在使用 StyleCop 4 7 Stylecop dll 中的 StyleCop msbuild 任务似乎依赖于 Microsoft Build Utilitie
  • 如何编写一个接受 int 或 float 的 C 函数?

    我想用 C 语言创建一个扩展 Python 的函数 该函数可以接受 float 或 int 类型的输入 所以基本上 我想要f 5 and f 5 5 成为可接受的输入 我认为我不能使用if PyArg ParseTuple args i v
  • 如何高效计算连续数的数字积?

    我正在尝试计算数字序列中每个数字的数字乘积 例如 21 22 23 98 99 将会 2 4 6 72 81 为了降低复杂性 我只会考虑 连续的数字 http simple wikipedia org wiki Consecutive in
  • 任何人都可以清楚地告诉如何在不使用像 这样的预定义函数的情况下找到带有小数值或小数值的指数吗? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 例如 2 0 5 1 414 所以想要 我是 c 的新手 所以请解释简单的逻辑 如果不是复杂的逻辑也足够了 在数学中 从整数取幂到实数
  • 从后面的代码添加外部 css 文件

    我有一个 CSS 文件 例如 SomeStyle css 我是否可以将此样式表文档从其代码隐藏应用到 aspx 页面 您可以将文字控件添加到标头控件中 Page Header Controls Add new System Web UI L
  • 嵌入式linux编写AT命令

    我在向 GSM 模块写入 AT 命令时遇到问题 当我使用 minicom b 115200 D dev ttySP0 term vt100 时它工作完美 但我不知道如何在 C 代码中做同样的事情 我没有收到任何错误 但模块对命令没有反应 有

随机推荐