Я разрешаю пользователю импортировать классы, подобные плагинам, из удаленного местоположения с помощью URLClassLoader, поэтому эти импортированные классы НЕ существуют в пути сборки (однако, все они реализуют интерфейс IPlugin , который включен).
Я предположил, что можно просто использовать ObjectOutputStream, чтобы сохранить все загруженные плагины в файл, а затем прочитать их с помощью ObjectInputStream. Однако, похоже, это не так, поскольку все, что он сохраняет, - это состояние объекта, а не содержащая его логика (т.е. методы).
Я бы хотел сохранить список загруженных плагинов (activePlugins) с помощью ObjectOutputStream:
ObjectOutputStream oos = new ObjectOutputStream(*fileoutputstream*);
oos.writeObject(activePlugins);
oos.close();
Затем в другой среде выполнения загрузить / восстановить все эти плагины с помощью ObjectInputStream:
ObjectInputStream ois = new ObjectInputStream(*fileinputstream*);
activePlugins = (ArrayList<IPlugin>) ois.readObject();
Но поскольку фактические классы объектов недоступны в пути сборки (они находятся где-то еще на жестком диске), это выходит из строя. То, что мне нужно, - это какой-то способ загрузки объектов без доступных классов, т.е. загрузка объектов с состояниями и без зависимостей. И вот ...
Итак, у меня есть ConfigurationSection / ConfigurationElementCollection, имеющая такую конфигурацию:
<mimeFormats>
<add mimeFormat="text/html" />
</mimeFormats>
И вот как я обрабатываю mimeFormats:
public class MimeFormatElement: ConfigurationElement
{
#region Constructors
/// <summary>
/// Predefines the valid properties and prepares
/// the property collection.
/// </summary>
static MimeFormatElement()
{
// Predefine properties here
_mimeFormat = new ConfigurationProperty(
"mimeFormat",
typeof(MimeFormat),
"*/*",
ConfigurationPropertyOptions.IsRequired
);
}
private static ConfigurationProperty _mimeFormat;
private static ConfigurationPropertyCollection _properties;
[ConfigurationProperty("mimeFormat", IsRequired = true)]
public MimeFormat MimeFormat
{
get { return (MimeFormat)base[_mimeFormat]; }
}
}
public class MimeFormat
{
public string Format
{
get
{
return Type + "/" + SubType;
}
}
public string Type;
public string SubType;
public MimeFormat(string mimeFormatStr)
{
var parts = mimeFormatStr.Split('/');
if (parts.Length != 2)
{
throw new Exception("Invalid MimeFormat");
}
Type = parts[0];
SubType = parts[1];
}
}
И, очевидно, мне нужен TypeConverter который на самом деле что-то делает (вместо этой пустой оболочки):
public class MimeFormatConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
throw new NotImplementedException();
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
throw new NotImplementedException();
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
throw new NotImplementedException();
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
Как мне настроить TypeConverter, который позволит преобразовывать типы из / в строку? Я пробовал использовать примеры MSDN, но все время получаю сообщение об ошибке:
TypeConverter не может преобразовать из System.String.
По сути, как его можно настроить так, чтобы он просто работал с тем, что ConfigurationSection пытается сделать ?