Неописанное блокирующее изменение в Microsoft Enterprise Library Validation Block 5.0
Неописанное блокирующее изменение в Microsoft Enterprise Library Validation Block 5.0
Если в Вашем проекте используется Microsoft Enterprise Library Validation Block — следует быть осторожным при переходе с версии 4.1.2 на версию 5.0. Помимо блокирующих изменений
описанных в документации существует еще одно (надеюсь только одно) неприятное отличие:
Если Ваше приложение использует сборку Microsoft.Practices.EnterpriseLibrary.Validation.dll не из собственной директории, а из GAC, то после обновления версии Enterprise Library валидация работать перестанет.
Что бы проиллюстрировать ошибку достаточно выполнить следующий тест
Положите библиотеки из Microsoft Enterprise Library 5.0 в GAC
Создайте простое консольное приложение, содержащее следующий код:
class Program
{
static void Main()
{
Microsoft.Practices.EnterpriseLibrary.Validation.Validation.Validate(new Model());
}
}
public class Model
{
[NotNullValidator]
public string Name { get; set; }
}
* This source code was highlighted with Source Code Highlighter.
Поставьте ссылку на Microsoft.Practices.EnterpriseLibrary.Validation.dll из GAC (также не забудьте подключить System.ComponentModel.DataAnnotations.dll – эта сборка необходима для использования NotNullValidatorAttribute )
Если Вы совершили все действия в правильной последовательности, то после запуска Вы получите исключение ActivationException с сообщением «Activation error occured while trying to get instance of type ValidatorFactory, key ""».
Пути решения
Если сборка находится в GAC, то после добавления этой сборки в проект в свойствах ссылки поле CopyLocal установлено в False. Если установить флаг в значение True – ошибка пропадет.
К сожалению, это решение подходит не для всех приложений. В частности, если все приложение находится в GAC (например приложение для Sharepoint) такое решение не сработает.
Вторым решением, является внесение изменений в конфигурационный файл приложения:
<configuration>
<configSections>
<section name="typeRegistrationProvidersConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.TypeRegistrationProvidersConfigurationSection, Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</configSections>
<typeRegistrationProvidersConfiguration>
<remove name="Validation" />
<add name="Validation" providerType="Microsoft.Practices.EnterpriseLibrary.Validation.Configuration.ValidationTypeRegistrationProvider, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</typeRegistrationProvidersConfiguration>
</configuration>
* This source code was highlighted with Source Code Highlighter.
Пояснение
Архитектура Enterprise Library 5.0 пересмотрена таким образом, что все блоки используют инверсию зависимостей (IoC). С одной стороны инверсия зависимостей должна свести к минимуму необходимость статических связей между концептуально независимыми сборками, c другой стороны разработчики старались сохранить совместимость с предыдущей версией Enterprise Library.
Из указанных требований вытекло решение, в котором некоторые классы, внутри сборки Microsoft.Practices.EnterpriseLibrary.Common, содержат имена типов из профильных сборок (таких как Microsoft.Practices.EnterpriseLibrary.Validation). Эти имена типов используются для позднего связывания, т.е. конкретный тип загружается по частичному имени (not fully qualified name). В результате, сборка, находящаяся в GAC и не присутствующая в соответствующем каталоге приложения, не может быть загружена, следствием чего является ActivationException исключение