我试图使用DBContextScopeFactory并遇到问题。
public class VendorRepository : IVendorRepository
{
private readonly IDbContextScopeFactory _dbContextScopeFactory;
public VendorRepository(IDbContextScopeFactory dbContextScopeFactory)
{
if (dbContextScopeFactory == null)
{
throw new ArgumentNullException("dbContextScopeFactory");
}
_dbContextScopeFactory = dbContextScopeFactory;
}
public IList<MyVendor> GetMyVendors(int requestorId)
{
IList<MyVendor> vndrsList = null;
using (var dbContextScope = _dbContextScopeFactory.CreateReadOnly())
{
var dbContext = dbContextScope.DbContexts.Get<VendorMgmtContext>();
var vndrs = (from a in dbContext.sp_GetVendorByRequestor(requestorId)
select new MyVendor
{
VendorId = a.VendorId,
VendorName = a.VendorName,
CreatedByUserId = a.CreatedByUserId,
CreatedDate = a.CreatedDate
});
vndrsList = vndrs.ToList();
}
return vndrsList;
}
}
单元测试工作得很好,因为它与演示应用程序项目类似。 (换句话说,我没有在UnityConfig.cs文件中注册它。
[TestMethod]
public void GetMyVendors()
{
// Arrange
var dbContextScope = new DbContextScopeFactory();
var db = new VendorMgmtContext();
VendorRepository repository = new VendorRepository(dbContextScope);
IEnumerable<MyVendor> myVendor = null;
// Act
myVendor = repository.GetMyVendors(3);
// Assert
Assert.IsNotNull(myVendor);
}
所以现在我不太确定如何在UnityConfig.cs文件中注册它 我试过了:
container.RegisterType<IAmbientDbContextLocator, AmbientDbContextLocator>();
container.RegisterType<IDbContextScopeFactory, DbContextScopeFactory>();
container.RegisterType<VendorMgmtContext, VendorMgmtContext>(new PerResolveLifetimeManager(), new InjectionConstructor());
container.RegisterType<IVendorRepository, VendorRepository>(new PerResolveLifetimeManager());
container.RegisterType<IVendorService, VendorService>(new PerResolveLifetimeManager());
但是我收到了一个服务器错误:“类型IDbContextFactory没有可访问的构造函数。”
我也尝试过:
container.RegisterType<IAmbientDbContextLocator, AmbientDbContextLocator>();
container.RegisterType<IDbContextScopeFactory, DbContextScopeFactory>(new InjectionFactory((a) => new DbContextScopeFactory()));
并且还收到了错误。我很确定这是我注册这个新实现的方式。提前感谢您的帮助。
更新:注册错误:
container.RegisterType<IDbContextScopeFactory, DbContextScopeFactory>(new InjectionFactory((a) => new DbContextScopeFactory()));
Message: "An error occurred when trying to create a controller of type 'VendorController'. Make sure that the controller has a parameterless public constructor"
ExceptionType: System.InvalidOperationException
StackTrace:
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()
InnerException:
Message: "Type 'Portal.Controllers.Api.VendorController' does not have a default constructor"
ExceptionType: System.ArgumentException
StackTrace:
at System.Linq.Expressions.Expression.New(Type type)
at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
更新#2 - 更新'Unity.AspNet.WebApi 3.5.1404.0'&amp;将Unity从“Unity 3.0.1304.1”更新为“Unity 3.5.1404.0”我还将所有注册从WebApiConfig.cs移至UnityConfig.cs文件。最后,我从
修改了Global.asax.cs UnityConfig.RegisterComponents();
到
UnityWebApiActivator.Start();
最后我的webAPI正在运行。然而,我仍然在MVC方面得到同样的例外。
[MissingMethodException:没有为此对象定义无参数构造函数。] System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,Boolean publicOnly,Boolean noCheck,Boolean&amp; canBeCached,RuntimeMethodHandleInternal&amp; ctor,Boolean&amp; bNeedSecurityCheck)+0 System.RuntimeType.CreateInstanceSlow(Boolean publicOnly,Boolean skipCheckThis,Boolean fillCache,StackCrawlMark&amp; stackMark)+119 System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly,Boolean skipCheckThis,Boolean fillCache,StackCrawlMark&amp; stackMark)+232 System.Activator.CreateInstance(Type type,Boolean nonPublic)+83 System.Activator.CreateInstance(类型类型)+11 System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext,Type controllerType)+110
[InvalidOperationException:尝试创建“Portal.Controllers.VendorController”类型的控制器时发生错误。确保控制器具有无参数的公共构造函数。] System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext,Type controllerType)+247 System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext,Type controllerType)+437 System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext,String controllerName)+257 System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext,IController&amp; controller,IControllerFactory&amp; factory)+326 System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext,AsyncCallback回调,对象状态)+157 System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext,AsyncCallback回调,对象状态)+88 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context,AsyncCallback cb,Object extraData)+50 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+103 System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean&amp; completedSynchronously)+155
我有一个构造函数
public class VendorController : Controller
{
IVendorService _VendorService;
public VendorController(IVendorService VendorSvc)
{
_VendorService = VendorSvc;
}
// GET: Vendor
public ActionResult Index()
{
return View();
}
}
答案 0 :(得分:1)
根据您发布的堆栈跟踪,您似乎正在尝试调用Web API控制器而不是ASP.NET Mvc控制器(因为问题的标记意味着)。此外,在注册期间但在实例化控制器期间未发生错误。
Web API尝试使用您没有的默认构造函数来实例化控制器(因为您预计会将依赖项注入构造函数中)。您需要将Unity设置为依赖项解析器以连接控制器依赖项。您可以从NuGet添加Unity bootstrapper for ASP.NET Web API。这将为您注册UnityDependencyResolver(在UnityWebApiActivator.cs中):
var resolver = new Microsoft.Practices.Unity.WebApi.UnityDependencyResolver(UnityConfig.GetConfiguredContainer());
GlobalConfiguration.Configuration.DependencyResolver = resolver;
您还可以将所有注册码移至UnityConfig.cs。
我发现您正在使用PerResolveLifetimeManager - 您可能需要考虑更改为使用随Unity bootstrapper for ASP.NET MVC一起安装的PerRequestLifetimeManager。 PerRequestLifetimeManager将在Web请求结束时自动处理IDisposable对象。
答案 1 :(得分:0)
错误消息清楚地说明了问题所在。您尚未正确设置IControllerFactory
或IDependencyResolver
以解析Unity的实例。这与您的注册无关。
ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
OR
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
请注意,您可以自己构建其中一个,也可以从某个地方使用库存实现。但请注意using IControllerFactory
is considered the "correct" approach to DI。