gpt4 book ai didi

c# - Unity Bootstrapper (Unity.Mvc), Unity 3, MVC 5, EF6 接收错误 : Parameterless Public Constructor on Controller

转载 作者:太空狗 更新时间:2023-10-30 01:19:23 25 4
gpt4 key购买 nike

好吧,在谷歌、这里和几个 ASP/MVC 论坛上搜索之后,我一定要问我到底做错了什么。

我的应用程序有一个良好的开端,对 DI、IoC 有很好的理解,并且正在使用 Repository、Service 和 UnitOfWork 模式。当我尝试从 Unity 加载需要 DI 的 Controller 时,就好像 unity 没有解析任何已注册的项目,或者我做得不好。从我可以看到的这个版本的所有示例(不是创建 Bootstrap.cs 文件然后从 Global.asax 调用的版本)我正在做其他人所做的事情,而没有 Unity 的支持。

我的核心问题是:我是否已设置/配置 Unity 以根据需要将项目注入(inject) Controller 构造函数。如果我有,为什么它不像我看到的例子那样工作有什么想法吗?

我不断收到 AssetController 需要具有无参数公共(public)构造函数的错误。如果我添加一个,它会在没有 DI 的情况下使用它,如果我不添加一个,它就会大喊没有它。

谢谢,下面的代码。

UnityConfig.cs

namespace CARS.web.App_Start
{
/// <summary>
/// Specifies the Unity configuration for the main container.
/// </summary>
public class UnityConfig
{
#region Unity Container
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});

/// <summary>
/// Gets the configured Unity container.
/// </summary>
public static IUnityContainer GetConfiguredContainer()
{
return container.Value;
}
#endregion

/// <summary>Registers the type mappings with the Unity container.</summary>
/// <param name="container">The unity container to configure.</param>
/// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to
/// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
public static void RegisterTypes(IUnityContainer container)
{
// NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
// container.LoadConfiguration();

// TODO: Register your types here
// container.RegisterType<IProductRepository, ProductRepository>();
container.RegisterType<IDataContext, CARSDEMOContext>(new PerRequestLifetimeManager())
.RegisterType<IAssetService, AssetService>()
.RegisterType<IUnitOfWork, UnitOfWork>()
.RegisterType<IRepository<Asset>, Repository<Asset>>();
//.RegisterType<AssetController>(new InjectionConstructor(typeof(IAssetService), typeof(IUnitOfWork)));
}
}
}

AssetController.cs(我正在执行注入(inject)参数的构造函数部分)

namespace CARS.web.Controllers
{
public class AssetController : Controller
{
private readonly IAssetService _assetService;
private readonly IUnitOfWork _unitOfWork;

public AssetController(IAssetService assetService, IUnitOfWork unitOfWork)
{
_assetService = assetService;
_unitOfWork = unitOfWork;
}
//other methods for CRUD etc stripped for brevity
}
}

IAssetService.cs(第一个参数是 assetService )

namespace CARS.service
{
public interface IAssetService : IService<Asset>
{
Task<IEnumerable<Asset>> GetAsync();
Task<Asset> FindAsync(Guid id);
Asset Add(Asset asset);
Asset Update(Asset asset);
void Remove(Guid id);
}
}

AssetService.cs(IAssetService交互的具体实现)

namespace CARS.service
{


public class AssetService : Service<Asset>, IAssetService
{
private readonly IRepositoryAsync<Asset> _repository;

public AssetService(IRepositoryAsync<Asset> repository) : base(repository)
{
_repository = repository;
}

public Task<IEnumerable<Asset>> GetAsync()
{
//return _repository.Query().SelectAsync();
return _repository.Query().SelectAsync();
}

public Task<Asset> FindAsync(Guid id)
{
return _repository.FindAsync(id);
}

public Asset Add(Asset asset)
{
_repository.Insert(asset);
return asset;
}

public Asset Update(Asset asset)
{
_repository.Update(asset);
return asset;
}

public void Remove(Guid id)
{
_repository.Delete(id);
}
}

}

IUnitOfWork.cs(这是来自 Long Le 的 Generic UofW and Repository - http://genericunitofworkandrepositories.codeplex.com/)

namespace Repository.Pattern.UnitOfWork
{
public interface IUnitOfWork : IDisposable
{
int SaveChanges();
Task<int> SaveChangesAsync();
void Dispose(bool disposing);
IRepository<TEntity> Repository<TEntity>() where TEntity : IObjectState;
void BeginTransaction();
bool Commit();
void Rollback();
}
}

UnitOfWork.cs(同样来自龙乐的框架)

namespace Repository.Pattern.Ef6
{
public class UnitOfWork : IUnitOfWork, IUnitOfWorkAsync
{
#region Private Fields

private readonly IDataContextAsync _dataContext;
private bool _disposed;
private ObjectContext _objectContext;
private Dictionary<string, object> _repositories;
private DbTransaction _transaction;

#endregion Private Fields

#region Constuctor/Dispose

public UnitOfWork(IDataContextAsync dataContext)
{
_dataContext = dataContext;
}

public void Dispose()
{
if (_objectContext != null && _objectContext.Connection.State == ConnectionState.Open)
_objectContext.Connection.Close();

Dispose(true);
GC.SuppressFinalize(this);
}

public virtual void Dispose(bool disposing)
{
if (!_disposed && disposing)
_dataContext.Dispose();
_disposed = true;
}

#endregion Constuctor/Dispose

public int SaveChanges()
{
return _dataContext.SaveChanges();
}

public IRepository<TEntity> Repository<TEntity>() where TEntity : IObjectState
{
return RepositoryAsync<TEntity>();
}

public Task<int> SaveChangesAsync()
{
return _dataContext.SaveChangesAsync();
}

public Task<int> SaveChangesAsync(CancellationToken cancellationToken)
{
return _dataContext.SaveChangesAsync(cancellationToken);
}

public IRepositoryAsync<TEntity> RepositoryAsync<TEntity>() where TEntity : IObjectState
{
if (_repositories == null)
_repositories = new Dictionary<string, object>();

var type = typeof (TEntity).Name;

if (_repositories.ContainsKey(type))
return (IRepositoryAsync<TEntity>) _repositories[type];

var repositoryType = typeof (Repository<>);
_repositories.Add(type, Activator.CreateInstance(repositoryType.MakeGenericType(typeof (TEntity)), _dataContext, this));

return (IRepositoryAsync<TEntity>) _repositories[type];
}

#region Unit of Work Transactions

public void BeginTransaction()
{
_objectContext = ((IObjectContextAdapter) _dataContext).ObjectContext;
if (_objectContext.Connection.State != ConnectionState.Open)
{
_objectContext.Connection.Open();
_transaction = _objectContext.Connection.BeginTransaction();
}
}

public bool Commit()
{
_transaction.Commit();
return true;
}

public void Rollback()
{
_transaction.Rollback();
((DataContext)_dataContext).SyncObjectsStatePostCommit();
}

#endregion

// Uncomment, if rather have IRepositoryAsync<TEntity> IoC vs. Reflection Activation
//public IRepositoryAsync<TEntity> RepositoryAsync<TEntity>() where TEntity : EntityBase
//{
// return ServiceLocator.Current.GetInstance<IRepositoryAsync<TEntity>>();
//}
}
}

已更新以包含来自 UnityMvcActivator.cs 的 SetResolver 信息

using System.Linq;
using System.Web.Mvc;
using Microsoft.Practices.Unity.Mvc;

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(CARS.web.App_Start.UnityWebActivator), "Start")]

namespace CARS.web.App_Start
{
/// <summary>Provides the bootstrapping for integrating Unity with ASP.NET MVC.</summary>
public static class UnityWebActivator
{
/// <summary>Integrates Unity when the application starts.</summary>
public static void Start()
{
var container = UnityConfig.GetConfiguredContainer();

FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));

DependencyResolver.SetResolver(new UnityDependencyResolver(container));

// TODO: Uncomment if you want to use PerRequestLifetimeManager
Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
}
}
}

我已经阅读/尝试了以下信息/数据,但没有任何解决办法:

The type IUserStore`1 does not have an accessible constructor

How to add MVC 5 authentication to Unity IoC?

Types not resolving with Unity [MVC 5]

我已经准备好必须为 Unity 编写一个 ControllerFactory 才能做到这一点,但是当我发现的所有示例都只注册了配置并且注入(inject)显然发生在 Controller 上时,这似乎需要大量工作和其他需要的类。

最后是错误:

The following server error was encountered: 
An error occurred when trying to create a controller of type 'CARS.web.Controllers.AssetController'. Make sure that the controller has a parameterless public constructor.Details are:
at System.Web.Mvc.DefaultControllerFactory.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionSte p.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

谢谢

最佳答案

您需要设置 DependencyResolver。我看不到您提供的示例中的代码。

设置 UnityContainer 并注册类型后,您需要设置 System.Web.MVC.DependencyResolver

 DependencyResolver.SetResolver(new UnityDependencyResolver(container));

关于c# - Unity Bootstrapper (Unity.Mvc), Unity 3, MVC 5, EF6 接收错误 : Parameterless Public Constructor on Controller,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23146775/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com