Есть несколько вариантов решения этой проблемы.В зависимости от того, как вы хотите масштабировать свое решение и насколько оно уже сложное, вы можете посмотреть на MAF (см. Пространство имен System.AddIn), поскольку это обрабатывает загрузку AddIns и уже поддерживает разделение AppDomain.Он также реализует целый набор функциональных возможностей, связанных с управлением временем жизни объектов, созданных в доменах приложений, а также загрузкой / выгрузкой надстроек и версиями.
Если вы предпочитаете реализовывать свои собственные или просто хотите больше разбираться в доменах приложений, тогда здесьэто пример, который, надеюсь, поможет.Он ничего не делает с настройкой AppDomain, безопасностью или управлением временем жизни, а для того, чтобы сделать код более компактным, нет обработки ошибок, но его можно использовать как руководство.
Если вы начинаете с примера, где Personобъект создается с фабрикой:
public class Person
{
internal Person(string name)
{
Name = name;
}
public string Name { get; private set; }
}
public class PersonFactory
{
public static Person CreatePerson(string name)
{
return new Person(name);
}
}
class Program
{
static void Main(string[] args)
{
Person p = PersonFactory.CreatePerson("John Smith");
}
}
Затем вы можете добавить к нему, чтобы создать Person в другом домене приложения с несколькими довольно простыми изменениями в приведенном выше коде.
Сделайте класс Person объектом MarshalByRefObject Добавьте еще одно свойство Person, которое будет выводить их домен приложения для тестирования Добавьте еще один статический метод на фабрику для создания в другом домене приложения
Исправленный код:
public class Person : MarshalByRefObject
{
internal Person(string name)
{
Name = name;
}
public string Name { get; private set; }
public string AppDomainName { get { return AppDomain.CurrentDomain.FriendlyName; } }
}
public class PersonFactory
{
public static Person CreatePerson(string name)
{
return new Person(name);
}
public static Person CreatePersonInAppDomain(string name, AppDomain domain)
{
return (Person)domain.CreateInstanceAndUnwrap(
typeof(Person).Assembly.FullName,
typeof(Person).FullName,
false,
BindingFlags.NonPublic | BindingFlags.Instance,
null,
new object[] { name },
null,
null
);
}
}
class Program
{
static void Main(string[] args)
{
AppDomain domain = AppDomain.CreateDomain("NewDomain");
Person person1 = PersonFactory.CreatePerson("John Smith");
Person person2 = PersonFactory.CreatePersonInAppDomain("Jane Smith", domain);
Console.WriteLine("Person: Name={0}, Domain={1}", person1.Name, person1.AppDomainName);
Console.WriteLine("Person: Name={0}, Domain={1}", person2.Name, person2.AppDomainName);
}
}
Вывод должен быть:
Person: Name=John Smith, AppDomain=[your exe name]
Person: Name=Jane Smith, AppDomain=NewDomain
Итак, что происходит?
Поскольку person2 являетсяобъект в другом AppDomain, он должен быть Serializable или наследоваться от MarshalByRefObject.В этом примере я получил производную от MarshalByRefObject, поэтому реальный экземпляр существует только во втором AppDomain, а ссылка в исходном AppDomain фактически является прокси.Если бы я выбрал реализацию Serializable, то копия этого человека будет передана обратно в исходный домен приложений.
Это что-то еще, что необходимо учитывать при каждом вызове нового домена приложений, любые параметры должны бытьмаршаллировал, что будет иметь некоторое влияние на производительность.Кроме того, необходимо учитывать и время жизни объекта, так как MarshalByRefObjects будет в конечном итоге истекать и будет собираться сборщиком мусора.Вам нужно будет изучить управление жизненным циклом, чтобы продлить его.