非常に単純なプラグインを作成するためのインターフェイスを作成しました。実際、これは実行時にdllファイルからロードされ、別のクラスにプロパティとして格納されるクラスにすぎません。インターフェイスを格納するそのクラスはシリアル化する必要があります。例として、これは私のシリアル化されたオブジェクトです。
<?xml version="1.0" encoding="utf-8"?><MD5HashMapper xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.namespace.net" />
しかし今、そのオブジェクトをロードしたい場合、例外が発生します:例として:
{"<MD5HashMapper xmlns='http://www.vrz.net/Vrz.Map'> was not expected."}
それで、誰かがその問題を解決する方法を知っていますか?
コード:dllファイルで共有されるIMapという名前のインターフェイスがあり、そのインターフェイスに基づいてアドインを作成します。
public interface IMap
{
object Map(object input);
}
私はまた異なるマッパーを持っています(あなたはそれらを通して入力を渡すことができ、それらは出力を変更します)。すべてのマッパーは以下から派生しています。
[XmlInclude(typeof(ConstMapper))]
[XmlInclude(typeof(FuncMapper))]
[XmlInclude(typeof(IdentMapper))]
[XmlInclude(typeof(NullMapper))]
[XmlInclude(typeof(RefMapper))]
[XmlInclude(typeof(VarMapper))]
[XmlInclude(typeof(TableMapper))]
[XmlInclude(typeof(AddinMapper))]
public class MapperBase:ComponentBase,IMap
{ public virtual object Map(object input) {
throw new NotImplementedException("Diese Methode muss überschrieben werden");
}
public override string ToString() {
return ShortDisplayName;
}
}
ComponentBaseを忘れてください。これには重要ではありません...
今、私はAddinMapperも持っています。そのマッパーの主な機能は、IMapオブジェクトからマッパーベースオブジェクトを作成することです。これは、マッパープロパティ(タイプIMap)のプロパティを含めて、まさに私がセラライズしたいクラスです。
public class AddinMapper : MapperBase
{
private static MapperBase[] _mappers;
const string addinDirectory = @"Addin\Mappers\";
//Mappers from *.dll files are loaded here:
[XmlIgnore]
public static MapperBase[] Mappers
{
get
{
if (_mappers == null)
{
List<MapperBase> maps = new List<MapperBase>();
foreach (string dll in Directory.GetFiles(addinDirectory, "*.dll"))
{
if (Path.GetFileName(dll) != "IMap.dll")
{
var absolutePath = Path.Combine(Environment.CurrentDirectory, dll);
Assembly asm = Assembly.LoadFile(absolutePath);
foreach (Type type in asm.GetTypes().ToList().Where(p => p.GetInterface("IMap") != null))
{
maps.Add(new AddinMapper((IMap)Activator.CreateInstance(type)));
}
}
}
Mappers = maps.ToArray();
}
return _mappers;
}
set
{
_mappers = value;
}
}
IMap _base;
public string MapperString { get; set; }
[XmlIgnore()]
public IMap Mapper
{
get
{
if (_base == null)
{
Type type = null;
foreach (MapperBase mapperBase in Mappers)
{
if (mapperBase is AddinMapper && ((AddinMapper)mapperBase).Mapper.GetType().FullName == _mapperName)
{
type = (mapperBase as AddinMapper).Mapper.GetType();
break;
}
}
if (type != null)
{
XmlSerializer serializer = new XmlSerializer(type);
using (StringReader reader = new StringReader(MapperString))
{
Mapper = (IMap)serializer.Deserialize(reader);
}
}
}
return _base;
}
private set
{
_base = value;
StoreMapperString();
}
}
string _mapperName;
[System.ComponentModel.Browsable(false)]
public string MapperName
{
get
{
return _mapperName;
}
set
{
_mapperName = value;
}
}
public AddinMapper(IMap baseInterface) : this()
{
Mapper = baseInterface;
_mapperName = baseInterface.GetType().FullName;
}
public AddinMapper()
{
}
public override object Map(object input)
{
return Mapper.Map(input);
}
public override string ToString()
{
return Mapper.ToString();
}
private void StoreMapperString()
{
MemoryStream memstream = new MemoryStream();
XmlStore.SaveObject(memstream, Mapper);
using (StreamReader reader = new StreamReader(memstream))
{
memstream.Position = 0;
MapperString = reader.ReadToEnd();
}
}
}
このようなアドインの例は次のとおりです。
public class ReplaceMapper : IMap
{
public string StringToReplace { get; set; }
public string StringToInsert { get; set; }
public object Map(object input)
{
if (input is string)
{
input = (input as string).Replace(StringToReplace, StringToInsert);
}
return input;
}
}
そして問題は、StringToReplaceなどの設定をxmlとして保存したいということです。