反射&应用设计 [英] Reflection & Application Design

查看:20
本文介绍了反射&应用设计的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我描述一下我目前遇到的问题和解决方案,也许你可以帮助我了解为什么这是一个坏主意(假设它是)以及我可以做些什么来使其成为一个更好的系统.

Let me describe the problem and the solution i currently have and maybe you can help enlighten me on why it's a bad idea (assuming it is) and what i can do to make it a better system.

现在我有 600 个撕裂者"来解析文件并将它们撕裂为 csv 或其他格式.rippers 都实现了一个公共接口和基类.在作业排队时,根据该作业的配置,使用反射调用特定的 ripper.

right now i have 600 "rippers" that parse files and rip them to csv or other formats. the rippers all implement a common interface and base class. At the moment when a job is queued up depending on the configuration of that job a specific ripper is called using reflection.

            foreach (var stream in streams)
            {
                try
                {
                    // load it
                    Assembly asm = Assembly.LoadFile(Path.Combine(stream.RipperPath, stream.RipperFileName), new Evidence());
                    if (asm == null)
                    {
                        MessageBox.Show(String.Format("Invalid Interface ripper loaded.\n{0}", Path.Combine(stream.RipperPath, stream.RipperFileName)));
                        return;
                    }

                    foreach (Type objType in asm.GetTypes())
                    {
                        if (!objType.IsPublic)
                            continue;

                        // make sure the type isn't Abstract
                        if (((objType.Attributes & TypeAttributes.Abstract) == TypeAttributes.Abstract))
                            continue;

                        // IRipper is the interface that all of the Rippers must implement to be loaded
                        Type objInterface = objType.GetInterface("IRipper", true);
                        if (objInterface == null)
                            continue;

                        try
                        {
                            var iri = (IRipper)Activator.CreateInstance(objType);

                            // Rippers must register with their hosts
                            iri.Host = this;
                            iri.OnStart += RipperStart;
                            iri.OnComplete += RipperComplete;
                            iri.OnProgressChanged += RipperStatusUpdate;
                            iri.dataStream = stream;
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(String.Format("Error loading interface: {0}\n{1}", Path.Combine(stream.RipperPath, stream.RipperFileName), ex.Message));
                }
            } 

所有开膛手都实现了一个名为Rip()"的函数,接口将它们收缩到该函数.

all rippers have implement a function called "Rip()" which the interface contracts them to.

使用当前代码,我能看到的唯一问题是在加载 600 个程序集后(因为它们在需要时加载),如果它们在使用后没有卸载,它将开始变得有点慢.

using the current code the only problem i can see is that after loading 600 assemblies (since they're loaded when they are needed) it's going to start getting a little slow if they are not unloaded after they have been used.

你有什么建议?

推荐答案

你真的有 600 个不同的 ripper,或者 600 个流和一些更少的 ripper 吗?您真的需要每个裂土器都在自己的组件中吗?如果您可以将裂土器组合在一起,您的组件可能会少得多.如果您的流详细信息包含类型名称以及可执行文件,则您可以有多个 ripper,您无需为它们查看程序集 - 只需调用 Assembly.GetType.

Do you actually have 600 different rippers, or 600 streams and some smaller number of rippers? Do you really need each ripper to be in its own assembly? If you could bunch the rippers together you could have far fewer assemblies. If your stream details contained the type name as well as the executable, you could have multiple rippers and you wouldn't need to go looking through the assembly for them - just call Assembly.GetType.

我不知道每个程序集到底有多少开销,请注意 - 我预计 600 个程序集会占用相当多的内存,但除此之外不会对性能产生太大影响.

I don't know how much overhead there really is per assembly, mind you - I'd expect 600 assemblies to take up a fair amount of memory, but not affect performance much beyond that.

整体方法似乎是合理的,尽管您可能还想查看 托管可扩展性框架 (MEF) - 对你的情况来说可能有点矫枉过正,但值得一看.我要做的另一件事是从处理流"代码中提取出获得开膛手":)

The overall approach seems reasonable, although you might also want to look at the Managed Extensibility Framework (MEF) - it may be overkill for your case, but worth a look. The other thing I'd do is factor out the "getting a ripper" from the "processing a stream" code :)

这篇关于反射&应用设计的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆