加载从 bin 中的程序集继承特定接口的类型

发布于 2024-12-27 00:16:48 字数 2042 浏览 2 评论 0原文

我正在编写 ASP.NET MVC 应用程序的代码,该应用程序在启动时将执行以下操作:

  • 加载应用程序 bin 目录中的所有程序集
  • 获取从接口派生的每个程序集的所有类型 (ITask)
  • 对每种类型调用 Execute() 方法

这是我目前想到的想法。此方法将在 OnApplicationStarted() 中调用:

    private void ExecuteTasks()
    {
        List<ITask> startupTasks = new List<ITask>();
        Assembly asm = this.ExecutingAssembly;

        // get path of executing (bin) folder 
        string codeBase = this.ExecutingAssembly.CodeBase;
        UriBuilder uri = new UriBuilder(codeBase);
        string path = Uri.UnescapeDataString(uri.Path);
        string bin = Path.GetDirectoryName(path);
        string[] assemblies = Directory.GetFiles(bin, "*.dll");

        foreach (String file in assemblies)
        {
            try
            {
                if (File.Exists(file))
                {
                    // load the assembly
                    asm = Assembly.LoadFrom(file);

                    // get all types from the assembly that inherit ITask
                    var query = from t in asm.GetTypes()
                                where t.IsClass &&
t.GetInterface(typeof(ITask).FullName) != null
                                select t;

                    // add types to list of startup tasks
                    foreach (Type type in query)
                    {
                        startupTasks.Add((ITask)Activator.CreateInstance(type));
                    }
                }
            }
            catch (Exception ex)
            {
                Exceptions.LogException(ex);
            }
        }

        // execute each startup task
        foreach (ITask task in startupTasks)
        {
            task.Execute();
        }
    }

我的问题:是否有更好的方法来执行这些步骤? 获取 bin 目录的方法取自此答案:https://stackoverflow.com/a/283917/213159。做一些简单的事情似乎需要做很多工作,但我找不到更简单的方法。

另外,使用 System.Activator 创建实例,然后在每个实例上调用 Execute() 方法是执行该步骤的最有效方法吗?

I am working on code for an ASP.NET MVC application that will do the following when the application is started:

  • Load all assemblies in the application bin directory
  • Get all types from each assembly that are derived from an interface (ITask)
  • Invoke the Execute() method on each type

Here is the current idea I came up with. This method will get called in OnApplicationStarted():

    private void ExecuteTasks()
    {
        List<ITask> startupTasks = new List<ITask>();
        Assembly asm = this.ExecutingAssembly;

        // get path of executing (bin) folder 
        string codeBase = this.ExecutingAssembly.CodeBase;
        UriBuilder uri = new UriBuilder(codeBase);
        string path = Uri.UnescapeDataString(uri.Path);
        string bin = Path.GetDirectoryName(path);
        string[] assemblies = Directory.GetFiles(bin, "*.dll");

        foreach (String file in assemblies)
        {
            try
            {
                if (File.Exists(file))
                {
                    // load the assembly
                    asm = Assembly.LoadFrom(file);

                    // get all types from the assembly that inherit ITask
                    var query = from t in asm.GetTypes()
                                where t.IsClass &&
t.GetInterface(typeof(ITask).FullName) != null
                                select t;

                    // add types to list of startup tasks
                    foreach (Type type in query)
                    {
                        startupTasks.Add((ITask)Activator.CreateInstance(type));
                    }
                }
            }
            catch (Exception ex)
            {
                Exceptions.LogException(ex);
            }
        }

        // execute each startup task
        foreach (ITask task in startupTasks)
        {
            task.Execute();
        }
    }

My question: is there a better way to do any of these steps? The method to get the bin directory was taken from this answer: https://stackoverflow.com/a/283917/213159. It seems like a lot of work to do something simple, but I couldn't figure out an easier approach.

Also, is using System.Activator to create instances and then subsequently invoke the Execute() method on each instance the most efficient way to perform that step?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

微凉 2025-01-03 00:16:48

您也许能够清理代码,但如果没有任何扩展库,代码不会变得那么短。

关于性能,我不会太担心优化 OnApplicationStarted 任务,特别是,希望它不会被频繁调用,并且一旦启动并运行就不会影响您的网站。

You may be able to clean the code up, but without any extension libraries the code doesn't get all that much shorter.

About performance, I'd not worry too much about optimizing OnApplicationStarted tasks in particular, it's hopefully not called all that often and shouldn't impact your site once it's up and running.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文