转换MEF应用程序以利用Rx(System.Reactive) [英] Converting a MEF application to utilize Rx (System.Reactive)

查看:132
本文介绍了转换MEF应用程序以利用Rx(System.Reactive)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以目前的情况是我有一个完全利用MEF的程序.现在,我想使其利用Rx来扩展到更大的查询,并允许用户在各种插件返回结果时查看结果.当前是这样设置的:

So the current situation is I have a program that is completely utilizing MEF. Now I want to make it utilize Rx as to allow it to scale to larger queries and allow the user to look over results as the various plugins return results. It is currently setup as such:

工作流程:查询=>确定类型=>查询插件=>结果

Workflow: Query => DetermineTypes => QueryPlugins => Results

当前,如果有人需要引用的内容超过我在下面发布的内容,则代码全部存储在GitHub上. GitHub上的ALeRT

Currently the code is all stored on GitHub if anyone needs to reference more than what I post below. ALeRT on GitHub

VS解决方案具有一个UI项目(默认为StartUp Project),一个PluginFramework项目,各种TypePlugin项目(请考虑一下类型,例如URL,电子邮件,文件,电话号码等)以及QueryPlugin项目(执行xyz(如果queryplugin支持已确定的类型).所有结果都通过DataTable的DefaultView映射到的DataGrid方式显示回UI中.

The VS solution has a UI project (default StartUp Project), a PluginFramework Project, various TypePlugin Projects (think determining what the type is such as a URL, Email, File, Phone Number, etc) and also QueryPlugin Projects (perform xyz if the queryplugin supports the type that has been determined). All the results are displayed back into the UI by ways of a DataGrid that is being mapped to by the DefaultView of a DataTable.

我想尝试使Rx部分对插件尽可能不可见.这是由于我不想为少数几个人编写插件变得复杂.因此,我正在考虑采用以下当前框架:

I want to try and make the Rx portion as invisible to the plugins as possible. This is due to the fact that I do not want to make writing plugins complex for the few people that will. So I was thinking about taking the current Framework below:

public interface IQueryPlugin
{
    string PluginCategory { get; }
    string Name { get; }
    string Version { get; }
    string Author { get; }
    System.Collections.Generic.List<string> TypesAccepted { get; }
    string Result(string input, string type, bool sensitive);
}

并将Result方法更改为以下内容:

and making the Result method into the following:

System.IObservable<string> Result(string input, string type, bool sensitive);

这自然需要修改调用插件的方法,该插件本身是:

This would naturally require modifying the method that is calling the plugin which as it stands is:

                using (GenericParserAdapter parser = new GenericParserAdapter())
                {
                    using (TextReader sr = new StringReader(qPlugins.Result(query, qType, sensitive)))
                    {
                        Random rNum = new Random();

                        parser.SetDataSource(sr);
                        parser.ColumnDelimiter = Convert.ToChar(",");
                        parser.FirstRowHasHeader = true;
                        parser.MaxBufferSize = 4096;
                        parser.MaxRows = 500;
                        parser.TextQualifier = '\"';

                        DataTable tempTable = parser.GetDataTable();
                        tempTable.TableName = qPlugins.Name.ToString();
                        if (!tempTable.Columns.Contains("Query"))
                        {
                            DataColumn tColumn = new DataColumn("Query");
                            tempTable.Columns.Add(tColumn);
                            tColumn.SetOrdinal(0);
                        }

                        foreach (DataRow dr in tempTable.Rows)
                        {
                            dr["Query"] = query;
                        }

                        if (!resultDS.Tables.Contains(qPlugins.Name.ToString()))
                        {
                            resultDS.Tables.Add(tempTable);
                        }
                        else
                        {
                            resultDS.Tables[qPlugins.Name.ToString()].Merge(tempTable);
                        }
                        pluginsLB.DataContext = resultDS.Tables.Cast<DataTable>().Select(t => t.TableName).ToList();
                    }
                }

因此,在这一点上,我仍然停留在如何使这项工作上的问题上.关于如何将MEF与Rx集成似乎没有很好的文档.我的假设是进行以下更改

So at this point I'm stuck as to how to make this work. There doesn't seem to be good documentation on how to integrate MEF with Rx. My assumption is to make the following change

using (TextReader sr = new StringReader(qPlugins.Result(query, qType, sensitive).Subscribe()))

但是这行不通.因此,对做出这些更改的任何帮助将不胜感激.如果您对我的代码有其他建议,请告诉我.我这样做是出于业余爱好,所以我知道我的代码肯定对大多数人来说不算什么.

but this isn't going to work. So any help on making these changes would be greatly appreciated. If you have other suggestions regarding my code, please let me know. I do this as a hobby so I know my code surely isn't up to snuff for most people.

推荐答案

这项工作对您有用吗?

IObservable<DataTable> q =
    from text in qPlugins.Result(query, qType, sensitive)
    from tempTable in Observable.Using(
        () => new GenericParserAdapter(),
        parser => Observable.Using(
            () => new StringReader(text),
            sr => Observable .Start<DataTable>(
                () =>
                {
                    var rNum = new Random();

                    parser.SetDataSource(sr);
                    parser.ColumnDelimiter = Convert.ToChar(",");
                    parser.FirstRowHasHeader = true;
                    parser.MaxBufferSize = 4096;
                    parser.MaxRows = 500;
                    parser.TextQualifier = '\"';

                    var tempTable = parser.GetDataTable();
                    tempTable.TableName = qPlugins.Name.ToString();
                    if (!tempTable.Columns.Contains("Query"))
                    {
                        DataColumn tColumn = new DataColumn("Query");
                        tempTable.Columns.Add(tColumn);
                        tColumn.SetOrdinal(0);
                    }

                    foreach (DataRow dr in tempTable.Rows)
                        dr["Query"] = query;

                    return tempTable;
                })))
    select tempTable;

这篇关于转换MEF应用程序以利用Rx(System.Reactive)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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