我在使用ASP.NET MVC 3在DefaultControllerFactory中使用DI设置解析Unity 2中已注册类型的命名注册时遇到问题。
在一个程序集中,我已经为Unity容器定义了注册类型和命名注册
public class VisUnityContainer : UnityContainer
{
public IUnityContainer RegisterVisComponents()
{
// register types
this
.RegisterType<ICompanyService, CompanyService>()
.RegisterType<ICompanyService, TestCompanyService>( "2" );
}
}
在我的MVC项目中,我继承了DefaultControllerFactory,我正在解析类型并传递VisUnityContainer
public class UnityControllerFactory : DefaultControllerFactory
{
private readonly IUnityContainer unityContainer;
public UnityControllerFactory( IUnityContainer unityContainer )
{
// set contracts
if( unityContainer == null )
throw new ArgumentNullException( null, "Unity container is not initialized." );
// set associations
this.unityContainer = unityContainer;
}
protected override IController GetControllerInstance( RequestContext requestContext, Type controllerType )
{
// set contracts
if( controllerType == null )
throw new HttpException( 404, String.Format( "The controller for path '{0}' could not be found or it does not implement IController.",
requestContext.HttpContext.Request.Path ) );
if( !typeof( IController ).IsAssignableFrom( controllerType ) )
throw new ArgumentException( String.Format( "Type requested is not a controller: {0}", controllerType.Name ) );
// action result
IController controller;
// company law
string companyLaw = String.Empty;
// set user properties
if( Thread.CurrentPrincipal != null &&
Thread.CurrentPrincipal.Identity.Name != null &&
!String.IsNullOrWhiteSpace( Thread.CurrentPrincipal.Identity.Name ) )
{
// set culture for law of companies region
CultureInfo cultureInfo = new CultureInfo( Profile.GetCurrent().CompanyState );
// set language
CultureInfo uiCultureInfo = new CultureInfo( Profile.GetCurrent().UserLanguage );
// set dates etc.
Thread.CurrentThread.CurrentCulture = cultureInfo;
// get proper resource file
Thread.CurrentThread.CurrentUICulture = uiCultureInfo;
// set company law
companyLaw = Profile.GetCurrent().CompanyLaw;
}
try
{
// resolve container
controller = this.unityContainer.Resolve( controllerType, companyLaw ) as IController;
}
catch( Exception )
{
// throw exception
throw new InvalidOperationException( String.Format( "Error resolving controller {0}", controllerType.Name ) );
}
// action end
return controller;
}
}
问题在于行
controller = this.unityContainer.Resolve( controllerType, companyLaw ) as IController;
虽然companyLaw等于2,但它不解析命名注册TestCompanyService,但始终解析CompanyService。如果我还使用某些命名注册设置CompanyService,则会抛出一个错误,说它无法解析类型。
另外,如果我尝试手动解析类似
的类型var test = this.unityContainer.Resolve<ICompanyService>( companyLaw );
返回正确的类型。
有人知道出了什么问题吗?
答案 0 :(得分:1)
Container.Resolve(type,string)
和
Container.Resolve<T>(string)
没有不同的方法。
Resolve(string)实际上是一个扩展方法,在内部调用Container.Resolve(type,string)。
查看代码,“controllerType”是一个类还是接口?如果“controllerType”是一个类(CompanyService)而不是一个接口(ICompanyService),它将始终解析为CompanyService。它还可以解释为什么当你尝试
时它会出错Resolve(controllerType,"2")
因为你在这里说的是:
container.Resolve(typeof(CompanyService),"2");
不存在。
这也可以解释为什么它在你打电话时有效:
container.Resolve<ICompanyService>("2");
因为你在这里设置了正确的界面
所以,简短回答:
我认为你传递的是具体的类类型而不是Unity的接口。应该相当容易检查。