Well, after a Google search, here and a few ASP / MVC forums, I definitely need to ask what the hell am I doing wrong here.
I have a good start for my application, a good understanding of DI, IoC, and the use of the Repository, Service, and UnitOfWork templates. When I try to load a controller that needs a DI from Unity, it as if unity does not allow any registered element or that I did it badly. Of all the examples that I can see for this version (and not the version that creates the Bootstrap.cs file, which is then called from Global.asax), I do what others did without the love of Unity.
My main question is: installed / configured Unity to enter elements into the controller’s constructor as necessary or not. If I have any ideas, why doesn't this work, like the examples I saw?
I keep getting the error that the AssetController should have a taskless public constructor. If I add one, then he will use it without DI, and if I do not add it, then he screams that he does not have it.
Thanks, the code is below.
UnityConfig.cs
namespace CARS.web.App_Start
{
public class UnityConfig
{
#region Unity Container
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
public static IUnityContainer GetConfiguredContainer()
{
return container.Value;
}
#endregion
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IDataContext, CARSDEMOContext>(new PerRequestLifetimeManager())
.RegisterType<IAssetService, AssetService>()
.RegisterType<IUnitOfWork, UnitOfWork>()
.RegisterType<IRepository<Asset>, Repository<Asset>>();
}
}
}
AssetController.cs (part of the constructor where I execute the insert options)
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;
}
}
}
IAssetService.cs (the first parameter is propertyService)
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 (specific implementation for IAssetService interaction)
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 - 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 ( Long Le)
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
}
}
, SetResolver UnityMvcActivator.cs
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
{
public static class UnityWebActivator
{
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));
Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
}
}
}
/ / :
IUserStore`1
MVC 5 Unity IoC?
, Unity [MVC 5]
, ControllerFactory Unity, , , , , -, .
, , :
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)