У меня есть поставщик членства, который создает проблему с внедрением зависимости. Я бы хотел понять, почему это происходит .
Это некоторые части базового контроллера. (Работает так, как должно.)
namespace Our.Web.Controllers
{
public abstract partial class OurBaseController : VABController
{
//--------------------------------------
// EVENT DECLARATIONS
//--------------------------------------
//--------------------------------------
// CLASS CONSTANTS
//--------------------------------------
//--------------------------------------
// PRIVATE VARIABLES
//--------------------------------------
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private UserInfo m_info;
//--------------------------------------
// PROTECTED VARIABLES
//--------------------------------------
//--------------------------------------
// CONSTRUCTOR & INITIALIZATION
//--------------------------------------
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
base.Initialize(requestContext);
logger.Debug("Initializing OurBaseController.");
m_info = UserInfoAccessor.GetCurrent();
}
//--------------------------------------
// GETTER/SETTERS
//--------------------------------------
[Dependency]
public UserInfoAccessor UserInfoAccessor { get; set; }
<snip>
}
}
Вот соответствующие части регистрации единства от Global.asax.cs:
namespace OurWeb
{
public class MvcApplication : System.Web.HttpApplication, IContainerAccessor
{
<snip>
//--------------------------------------
// GETTER/SETTERS
//--------------------------------------
IUnityContainer IContainerAccessor.Container
{
get { return MvcUnityContainer.Container ; }
}
//--------------------------------------
// EVENT HANDLERS
//--------------------------------------
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
ConfigureUnity();
<snip>
}
<snip>
//--------------------------------------
// STATIC METHODS
//--------------------------------------
<snip>
//--------------------------------------
// PRIVATE & PROTECTED INSTANCE METHODS
//--------------------------------------
private void ConfigureUnity()
{
//Create UnityContainer
IUnityContainer container = new UnityContainer()
<snip>
.RegisterType<UserInfoAccessor>()
<snip>
//Set container for Controller Factory
MvcUnityContainer.Container = container;
<snip>
//Set Controller Factory as UnityControllerFactory
ControllerBuilder.Current.SetControllerFactory(
typeof(UnityControllerFactory));
}
<snip>
}
}
Теперь, когда я добавляю пользовательский провайдер членства, я не могу внедрить его, поэтому я использовал BuildUp в конструкторе.
namespace System.Web.Security
{
public class OurMembershipProvider : SqlMembershipProvider
{
//--------------------------------------
// EVENT DECLARATIONS
//--------------------------------------
//--------------------------------------
// CLASS CONSTANTS
//--------------------------------------
//--------------------------------------
// PRIVATE VARIABLES
//--------------------------------------
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
//--------------------------------------
// PROTECTED VARIABLES
//--------------------------------------
//--------------------------------------
// CONSTRUCTOR & INITIALIZATION
//--------------------------------------
public OurMembershipProvider()
: base()
{
// Can't inject so we'll ask the container to build the instance.
IUnityContainer container = GetUnityContainer();
container.BuildUp(this);
}
//--------------------------------------
// GETTER/SETTERS
//--------------------------------------
[Dependency]
public UserInfoAccessor UserInfoAccessor { get; set; }
//--------------------------------------
// PUBLIC METHODS
//--------------------------------------
public override bool ValidateUser(string username, string password)
{
//Sufficient for the question. In reality it contains account mapping validation logic.
return base.ValidateUser(username, password);
}
//--------------------------------------
// EVENT HANDLERS
//--------------------------------------
//--------------------------------------
// STATIC METHODS
//--------------------------------------
//--------------------------------------
// PRIVATE & PROTECTED INSTANCE METHODS
//--------------------------------------
private IUnityContainer GetUnityContainer()
{
var context = HttpContext.Current;
if (context == null)
throw new Exception("No HttpContext");
var accessor = context.ApplicationInstance as IContainerAccessor;
if (accessor == null)
throw new Exception("The global HttpApplication instance needs to implement " + typeof(IContainerAccessor).FullName);
if (accessor.Container == null)
throw new Exception("HttpApplication has no container initialized");
return accessor.Container;
}
}
}
Класс находится в веб-проекте MVC, поэтому я просто изменил файл web.config следующим образом:
<!--<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" applicationName="/"/>-->
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.OurMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" applicationName="/"/>
Теперь, когда я это сделал, я получаю исключение нулевой ссылки в конструкторе OurBaseController
в этой строке: m_info = UserInfoAccessor.GetCurrent();
Почему Unity не внедряет UserInfoAccessor, когда я регистрирую этого провайдера нестандартного членства, но он работает нормально, когда я возвращаюсь к стандартному провайдеру?
BuildUp мешает инъекции?
Я не получаю никаких других исключений в отладчике или в elmah.
РЕЗОЛЮЦИЯ 20110726
Пользовательский объект членства был создан при настройке UnityContainer. Это сделало контейнер недоступным, а исключение во время инициализации привело к тому, что UnityContainer остался не инициализированным, поэтому контейнер был недоступен.
Чему я научился из этого?
Использование контейнера для единства в качестве локатора ресурсов может привести к появлению червей.
Почему я пропустил ошибку во время настройки?
Когда я запустил сайт, мой веб-браузер открыл новую вкладку. Я отказался от этого и обновил более раннее окно. Поэтому я смотрел на результат второго запроса, в котором сайт уже был запущен.