Unity Bootstrapper (Unity.Mvc), Unity 3, MVC 5, EF6 Error on receipt: Parametric public constructor on the controller

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
{
    /// <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 (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;
        }
        //other methods for CRUD etc stripped for brevity
    }
}

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

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

, 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
{
    /// <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));
        }
    }
}

/ / :

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)

+4
3

DependencyResolver. , , .

UnityContainer System.Web.MVC.DependencyResolver.

 DependencyResolver.SetResolver(new UnityDependencyResolver(container));
+4

, ( ), UnityConfig.cs
, :

container.RegisterType<IUnitOfWork, UnitOfWork>(new PerRequestLifetimeManager())
            .RegisterType<IUnitOfWorkAsync, UnitOfWork>(new PerRequestLifetimeManager())
            .RegisterType<IDataContextAsync, SomeDBContext>(new PerRequestLifetimeManager())
            .RegisterType<IDataContext, SomeDBContext>(new PerRequestLifetimeManager())
            .RegisterType<ISomeService, SomeService>(new PerRequestLifetimeManager())
            .RegisterType<IRepositoryAsync<Some>, Repository<Some>>(new PerRequestLifetimeManager());
0

1: Uncomment UnityMvcActivator:

Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));

2: The main registration in Unity + UnitOfwork + repository this should exist in the file: UnityConfig :

container.RegisterType<IDataContextAsync, KlussendirectContext>(new PerRequestLifetimeManager());
container.RegisterType<IDataContext, KlussendirectContext>(new PerRequestLifetimeManager());
container.RegisterType<IUnitOfWork, UnitOfWork>(new PerRequestLifetimeManager());
container.RegisterType<IUnitOfWorkAsync, UnitOfWork>(new PerRequestLifetimeManager());

3: When you use dependency injection in the controller (api), then there is a constructor with a lower parameter value: for example.

 public MyNameController() : base(){}

If you follow these steps, it should work (Edit, Insert, Delete, etc.)

0
source

Source: https://habr.com/ru/post/1537043/


All Articles