Замена сборок, которые загружаются только через отражение - PullRequest
2 голосов
/ 26 июня 2011

в проекте, над которым я сейчас работаю, у нас есть ряд классов, экземпляры которых создаются только с помощью отражения, и сборки, к которым они принадлежат, не упоминаются никаким другим классом.

Эта схема позволяет заменить сборку во время выполнения, чтобы расширить / исправить функциональные возможности предыдущей. Обратите внимание, что в нашем конкретном случае невозможно использовать MarshalByRefObject, и поэтому разные версии одной и той же сборки, содержащие классы с одинаковыми именами, но разными функциями, в конечном итоге загружаются в одном домене приложений.

Я представляю чрезвычайно упрощенный пример: рассмотрим следующее объявление интерфейса и консольное приложение

public interface ISomeInterface
{
    string getData();
}

class Program
{
    static void Main(string[] args)
    {
        byte[] lastLibrary = null;
        Assembly lastAssembly = null;

        while (true)
        {
            byte[] theLibrary = File.ReadAllBytes("ClassLibrary1.dll");

            if (lastLibrary == null || !theLibrary.SequenceEqual(lastLibrary))
            {
                lastAssembly = Assembly.Load(theLibrary);
            }

            ISomeInterface obj = lastAssembly.CreateInstance("ClassLibrary1.Class1") as ISomeInterface;

            Console.WriteLine(obj.getData());

            lastLibrary = theLibrary;
            Thread.Sleep(1000);
        }
    }
}

вместе со следующей реализацией интерфейса (на отдельной сборке):

public class Class1 : ISomeInterface
{
    public string getData()
    {
        return "someText";
    }
}

Как и ожидалось, если я изменю реализацию ISomeInterface (например, изменив «someText» на «someOtherText») и заменим старый dll новым, будет использоваться самая последняя версия. Однако мне интересно: какова вероятность того, что этот механизм вызовет проблемы со стабильностью программного обеспечения? Я имею в виду, все ли безопасно, пока я не создаю экземпляры этих классов только с помощью отражения, и никакой другой компонент не ссылается на них? Что касается наших предварительных тестов, похоже, что все работает нормально, но я хотел бы услышать также от экспертов.

Я знаю, что в этом конкретном примере было бы возможно использовать MarshalByRefObject для выполнения всего, но, как я уже говорил, мы не можем идти в этом направлении.

1 Ответ

4 голосов
/ 26 июня 2011

Что-то вроде этого должно работать нормально, но я думаю, что вы не понимаете, что на самом деле происходит.

Когда вы загружаете сборку в домен приложений, она никогда не освобождается, покаэтот AppDomin существует.Что вы делаете, чтобы загрузить новую сборку.Но, делая это, вы не выпускаете старую версию.Например, если объект из предыдущей версии все еще существует, он вернет «someText», даже если вновь созданный объект вернет «someOtherText».И хотя имя типа обоих этих объектов ClassLibrary1.Class1, они бывают разных типов.

Если это поведение для вас правильно, то с вами все будет в порядке.Но не забывайте, что все старые версии по-прежнему загружаются и, таким образом, хранятся в памяти, поэтому при этом происходит утечка памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...