我有一个基于插件的主机应用程序。 其设置被描述为数据合同:

[DataContract(IsReference = true)]
public class HostSetup
{
    [DataMember]
    public ObservableCollection<Object> PluginSetups
    {
        get
        {
            return pluginSetups ?? (pluginSetups = new ObservableCollection<Object>());
        }
    }
    private ObservableCollection<Object> pluginSetups;          
}

任何插件都有自己的设置类型。 E. g。:

[DataContract(IsReference = true)]
public class Plugin1Setup
{
    [DataMember]
    public String Name { get; set; }
}

[DataContract(IsReference = true)]
public class Plugin2Setup
{
    [DataMember]
    public Int32 Percent { get; set; }
    [DataMember]
    public Decimal Amount { get; set; }
}

在运行时,用户已经配置了主机和插件:

        var obj = new HostSetup();
        obj.PluginSetups.Add(new Plugin1Setup { Name = "Foo" });
        obj.PluginSetups.Add(new Plugin2Setup { Percent = 3, Amount = 120.50M });

然后,我的应用程序已通过DataContractSerializer保存其设置。 插件类型作为已知类型传递给序列化程序的构造函数。

这个问题。
用户使用“Plugin2”物理删除程序集,然后启动我的应用程序。
因此,当主机收到可用插件列表时,它对序列化的“Plugin2Setup”实例一无所知。

我想忽略这个实例,让用户在没有“Plugin2”设置的情况下工作。
有没有优雅的方法来做到这一点?
我可以将数据合同序列化为字符串时存储插件的设置:

public ObservableCollection<String> PluginSetups  

但它不方便和丑陋。

编辑1
问题是如何反序列化HostSetup实例并忽略序列化的Plugin2Setup实例。

编辑2
我目前的解决方案是:

[DataContract(IsReference = true)]
public class PluginSetupContainer
{
    [DataMember]
    private String typeName;
    [DataMember]
    private String rawData;

    [OnSerializing]
    private void OnSerializing(StreamingContext context)
    {
        if (SetupParameters != null)
        {
            using (var writer = new StringWriter())
            using (var xmlWriter = new XmlTextWriter(writer))
            {
                var setupParametersType = SetupParameters.GetType();
                var serializer = new DataContractSerializer(setupParametersType);
                serializer.WriteObject(xmlWriter, SetupParameters);

                xmlWriter.Flush();

                typeName = setupParametersType.AssemblyQualifiedName;
                rawData = writer.ToString();
            }
        }
    }

    [OnSerialized]
    private void OnSerialized(StreamingContext context)
    {
        ClearInternalData();
    }

    [OnDeserialized]
    private void OnDeserialized(StreamingContext context)
    {
        if (!String.IsNullOrEmpty(typeName) && !String.IsNullOrEmpty(rawData))
        {
            var setupParametersType = Type.GetType(typeName, false);
            if (setupParametersType != null)
            {
                using (var reader = new StringReader(rawData))
                using (var xmlReader = new XmlTextReader(reader))
                {
                    var serializer = new DataContractSerializer(setupParametersType);
                    SetupParameters = serializer.ReadObject(xmlReader);
                }
            }

            ClearInternalData();
        }
    }

    private void ClearInternalData()
    {
        typeName = null;
        rawData = null;
    }

    public Object SetupParameters { get; set; }
}

[DataContract(IsReference = true)]
public class HostSetup
{
    [DataMember]
    public ObservableCollection<PluginSetupContainer> PluginSetups
    {
        get
        {
            return pluginSetups ?? (pluginSetups = new ObservableCollection<PluginSetupContainer>());
        }
    }
    private ObservableCollection<PluginSetupContainer> pluginSetups;
}

可能它很糟糕,但它确实有效。 :)

===============>>#1 票数:0

我认为理想情况下你应该有一些东西

[DataContract(IsReference = true)]
[MyPluginCustomAttribute]
public class Plugin1Setup
{
}

当您加载应用程序时,您应该使用基于MyPluginCustomAttribute反射初始化obj.PluginSetups ,这样只有存在的程序集才会注册其类型。 所以你不会有丢失程序集的问题。 您还可以使用Managed Extensibility Framework(MEF)而不是您自己的MyPluginCustomAttribute

  ask by Dennis translate from so

未解决问题?本站智能推荐:

1回复

在C#中使用数据协定进行Xml反序列化期间出错

我知道争论已经面对了很多次,但是我是一个新手,我不知道如何处理错误。 我有一个Stream XML,我想用数据协定方法反序列化它。 您注意到我在哪里做错了吗? 这是xml: 这是数据合同: 这是代码: 这是例外: 该请求被中止:连接意外关闭。
1回复

DataContractJsonSerializer对Json反序列化

我正在尝试反序列化Json String。 我的反序列化功能适用于OrderData 。 当我反序列化时, OrderData始终为null并且SourceData也不会显示。 它也不会引发任何错误。 有什么建议可以解决这个问题吗? 我的反序列化代码在这里: 这是我使用的
2回复

datacontractserializer反序列化列表<>始终为空

我正在反序列化从Web服务收到的数据。 问题是List的反序列化将返回一个空列表,并且不会生成任何异常。 你能帮我弄清楚为什么吗? 我们尝试了几种可能的语法。 下面的代码最接近正确的解决方案,但是我们不能正确地反序列化为类列表。 码: 类:
3回复

如何正确反序列化XML属性和数组?

我正在做一个C#项目,我有一个用XML编码的对象。 一个示例实例为: 我需要属性信息,因为它是对象具有的键-值对的必要条件。 我的反序列化语法如下所示: 现在,它不起作用。 目前它解析为Fields元素,然后它的任何子级都为null 。
1回复

C#JSON反序列化iTunes搜索API

我只是无法使这种反序列化工作。 它没有错误,但artistName保持为空。 有人可以帮忙吗? Json字符串: {“ resultCount”:1,“ results”:[{“ wrapperType”:“ track”,“ kind”:“ song”,“ artistId
3回复

如何在XML中对C#WCF DataContract进行序列化/反序列化

我正在开发WCF服务,该服务将由多个不同的客户端应用程序使用。 为了使一种功能起作用,服务器需要将XML文件读取到C#DataContract中,然后将其传递给有关的客户端。 据我从MSDN网站了解,这是可能的,但我找不到完整的示例。 特别是,该网站谈论的是“流”参数,我还不太了解。
1回复

C#Json反序列化整数以键入实例

考虑以下给定的json字符串: 有没有办法使用System.Runtime.Serialization.DataContractAttribute和System.Runtime.Serialization.Json.DataContractJsonSerializer将last_acti
1回复

如何在WCF中使用自定义序列化或反序列化来强制datacontact的每个属性上的新实例?

我有一个datacontact,其中有许多成员都有自定义类 如果在反序列化时属性为null,我想强制一个新实例。 有没有办法做到这一点?
2回复

在(反)序列化树中使用自己的XmlSerializer将已知类型的列表传递给对象

我在microsoft .net 3.5(VS2008)上使用C#3。 我有反序列化的问题。 我在我想要序列化的类层次结构中使用DataContract和DataMember。 但是,我在一个容器中也有多态,所以我需要将已知类型的列表传递给序列化器。 我的收藏是一个可在网上找到的可序
2回复

如何序列化继承内置c#类的对象?

我正在尝试创建一个将应用程序当前状态保存到文件的函数,以及另一个加载已保存文件的函数。 当前,所有信息都包含在单个对象中,而单个对象又指向其他对象。 最近,我听说C#具有一些内置类,可帮助您序列化和反序列化对象,因此我做了一些研究,并从以下页面了解了DataContracts: http :