Base solution for your next web application
Open Closed

Can't create component, A dependency cannot be satisfied by #159


User avatar
0
sayram created

K. I'm trying to build my web application. It's a normal Mvc web application.

Well i created a model named Category. here it is.

public class Category : Entity<int>, ISoftDelete, IPassivable
    {
        public Category()
        {
            this.SubCategories = new List<Category>();
            IsActive = true;
            IsDeleted = false;
        }

        [ForeignKey("ParentId")]
        public int? ParentId { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public bool IsActive { get; set; }
        public bool IsDeleted { get; set; }
        public virtual ICollection<Category> SubCategories { get; set; }
        public virtual Category ParentCategory { get; set; }
    }

well i created ICategoryService interface and CategoryService class.

public interface ICategoryService : IApplicationService
    {
        GetCategoryOutput GetCategories(GetCategoryInput input);
        void UpdateCategory(UpdateCategoryInput input);
        void CreateCategory(CreateCategoryInput input);
    }
public class CategoryService : ApplicationService, ICategoryService
    {
        private readonly  ICategoryRepository _categoryRepository;
        private readonly ICategoryService _categoryService;
        
        public CategoryService(ICategoryService categoryService, ICategoryRepository categoryRepository)
        {
            _categoryService = categoryService;
            _categoryRepository = categoryRepository;
        }

        public GetCategoryOutput GetCategories(GetCategoryInput input)
        {
            var categories = _categoryRepository.GetCategories(input.IsActive, input.IsDeleted);

            return new GetCategoryOutput
            {
                Categories = Mapper.Map<List<CategoryDto>>(categories)
            };
        }

        public void CreateCategory(CreateCategoryInput input)
        {
            Logger.Info("Creating a category for input: " + input);

            //Creating a new category with given input's parametes
            var category = new Category
            {
                ParentId = input.ParentId,
                Title = input.Title,
                Description = input.Description
            };

            if (input.ParentId.HasValue)
            {
                category.ParentCategory = _categoryRepository.Load((input.ParentId.Value));
            }

            _categoryRepository.Insert((category));
        }


        public void UpdateCategory(UpdateCategoryInput input)
        {
            Logger.Info("Updatinga category for input: " + input);

            var category = _categoryRepository.Get(input.CategoryId);


            if (input.ParentId.HasValue)
            {
                category.ParentCategory = _categoryRepository.Load((input.ParentId.Value));
            }

            //We even do not call Update method of the repository.
            //Because an application service method is a 'unit of work' scope as default.
            //ABP automatically saves all changes when a 'unit of work' scope ends (without any exception).
        }
    }

I've added an Area named Administrator and a Controller named CategoryController.

public class CategoryController : BisahneControllerBase
    {
        private ICategoryService _categoryService;

        public CategoryController(ICategoryService categoryService)
        {
            _categoryService = categoryService;
        }

        //
        // GET: /Administrator/Category/
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Create(CategoryDto categoryDto)
        {
            return View();
        }

	}

when i run the application and browse the Administrator/Category/Create i'm getting an error like below

Can't create component 'Bisahne.Categories.CategoryService' as it has dependencies to be satisfied.

'Bisahne.Categories.CategoryService' is waiting for the following dependencies:

  • Service 'Bisahne.Categories.ICategoryService' which points back to the component itself. A dependency cannot be satisfied by the component itself, did you forget to register other components for this service?

Do i have to register something anywhere?


13 Answer(s)
  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    You are trying to inject ICategoryService into CategoryService that is not possible and not necessary. I think you did it by mistake.

  • User Avatar
    0
    sayram created

    Yes i saw this when i check my codes. I remembered now. I was trying ReSharper shortcuts (Introduce Field) Sorry for unnecessary topic.

  • User Avatar
    0
    nobruds created

    Hello,

    Can I hijack this post ? I have the same issue here, but I am not trying to inject IService into Service. My error occurs on IRepository, but its the same as others services that I have that works:

    Can't create component 'GerenciadorBoletador.Status.StatusOperacaoService' as it has dependencies to be satisfied.
    
    'GerenciadorBoletador.Status.StatusOperacaoService' is waiting for the following dependencies:
    - Service 'GerenciadorBoletador.Status.IStatusOperacaoRepository' which was not registered.
    
    namespace GerenciadorBoletador.Status 
    {
        public interface IStatusOperacaoRepository : IRepository<StatusOperacao>
        {
        }
    }
    
    namespace GerenciadorBoletador.Status
    {
        public interface IStatusOperacaoService : IApplicationService
        {
            List<StatusOperacao> GetStatusOperacao();
        }
    }
    
    namespace GerenciadorBoletador.Status 
    {
        public class StatusOperacaoService : IStatusOperacaoService
        {
            private readonly IStatusOperacaoRepository _statusOperacaoRepository;
    
            public StatusOperacaoService(IStatusOperacaoRepository statusOperacaoRepository)
            {
                _statusOperacaoRepository = statusOperacaoRepository;
            }
    
            public List<StatusOperacao> GetStatusOperacao()
            {
                List<StatusOperacao> result = null;
    
                try
                {
                    result = _statusOperacaoRepository.GetAllList();                
                }
                catch (Exception ex)
                {
                    throw ex;
                }
    
                return result;
            }
        }
    }
    
    namespace GerenciadorBoletador.NHibernateData.Repositories
    {
        public class StatusOperacaoRespository : NhRepositoryBase<StatusOperacao>, IStatusOperacaoRepository
        {
            public StatusOperacaoRespository(ISessionProvider sessionProvider)
                : base(sessionProvider)
            {
            }
        }
    }
    

    EDIT: Weird stuff, i changed the service to be like this:

    private readonly IRepository<StatusOperacao> _statusOperacaoRepository;
            public StatusOperacaoService(IRepository<StatusOperacao> statusOperacaoRepository)
            {
                _statusOperacaoRepository = statusOperacaoRepository;
            }
    

    and worked. So, whats wrong with my custom IStatusOperacaoRepository, its just an Interface that extends IRepository<StatusOperacao>

  • User Avatar
    0
    hikalkan created
    Support Team

    Have you implemented and registered IStatusOperacaoRepository? Can you share it here?

  • User Avatar
    0
    nobruds created

    Isn't the implementation my StatusOperacaoRespository ? I don´t have additional methods on this one

    I registered like this:

    class Program
        {
            static void Main(string[] args)
            {
                using (var bootstrapper = new AbpBootstrapper())
                {
                    bootstrapper.Initialize();
                    Test_Way_1(bootstrapper.IocManager);
                }
            }
    
            private static void Test_Way_1(IIocManager iocManager)
            {
                var tester = iocManager.Resolve<Tester>();
                tester.Test();
                iocManager.Release(tester);
            }
        }
    
    class Tester : ITransientDependency
        {
            private readonly IStatusOperacaoService _gopAppService;
    
            public Tester( IStatusOperacaoService gopAppService)
            {
                _gopAppService = gopAppService;
            }
    
            public void Test()
            {
                var result = _gopAppService.GetStatusOperacao();
            }
        }
    

    And I have the Module:

    [DependsOn(typeof(GerenciadorBoletadorDataModule), typeof(GerenciadorBoletadorApplicationModule))]
        public class GerenciadorBoletadorAppModule : AbpModule
        {
            public override void Initialize()
            {
                IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
            }
        }
    

    EDIT: Could this be related with namespace or something like it? because I have other repositories just like that and works fine.

  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    I suppose that did not understand well. If you defined IStatusOperacaoRepository then it should have some implementation (probably named class StatusOperacaoRepository), even it does not define any method and just inherit IRepository<StatusOperacao>. So, your implementation also just extend your base repository, not adds any method. But, for such cases, just use IRepository<StatusOperacao>, don't define an empty repository if not needed.

  • User Avatar
    0
    nobruds created

    Hi,

    Yes, I understood that, I have the implementation class for the Interface as I showed in the code quotes. For this case its ok if I don't use custom repository, but the question is Why works for other services and not this one, as it is the same. And in the future I will add some custom methods there

    I will post my code again, I missed something?

    Thanks

    Repository Interface:

    namespace GerenciadorBoletador.Status 
    {
        public interface IStatusOperacaoRepository : IRepository<StatusOperacao>
        {
        }
    }
    

    Service Interface

    namespace GerenciadorBoletador.Status
    {
        public interface IStatusOperacaoService : IApplicationService
        {
            List<StatusOperacao> GetStatusOperacao();
        }
    }
    

    Service Implementation

    namespace GerenciadorBoletador.Status 
    {
        public class StatusOperacaoService : IStatusOperacaoService
        {
            private readonly IStatusOperacaoRepository _statusOperacaoRepository;
    
            public StatusOperacaoService(IStatusOperacaoRepository statusOperacaoRepository)
            {
                _statusOperacaoRepository = statusOperacaoRepository;
            }
    
            public List<StatusOperacao> GetStatusOperacao()
            {
                List<StatusOperacao> result = null;
    
                try
                {
                    result = _statusOperacaoRepository.GetAllList();                
                }
                catch (Exception ex)
                {
                    throw ex;
                }
    
                return result;
            }
        }
    }
    

    Repository Implementation

    namespace GerenciadorBoletador.NHibernateData.Repositories
    {
        public class StatusOperacaoRespository : NhRepositoryBase<StatusOperacao>, IStatusOperacaoRepository
        {
            public StatusOperacaoRespository(ISessionProvider sessionProvider)
                : base(sessionProvider)
            {
            }
        }
    }
    
  • User Avatar
    0
    hikalkan created
    Support Team

    I found it :)

    It's a typing error: StatusOperacaoRe**<span style="color:#FF0000">s</span>**pository is wrong, it should be StatusOperacaoRepository.

    See docs: <a class="postlink" href="http://www.aspnetboilerplate.com/Pages/Documents/Dependency-Injection#DocConventionalRegister">http://www.aspnetboilerplate.com/Pages/ ... alRegister</a>

    From document:

    "Naming conventions are very important here. For example you can change name of PersonAppService to MyPersonAppService or another name which contains 'PersonAppService' postfix since the IPersonAppService has this postfix. But you can not name your service as PeopleService. If you do it, it's not registered for IPersonAppService automatically (It's registered to DI framework but with self-registration, not with interface), so, you should manually register it if you want."

  • User Avatar
    0
    nobruds created

    OMG, really ? haha Sorry, my bad, I missed that. too much hours on this :o

    Thank you. bruno

    <cite>hikalkan: </cite> I found it :)

    It's a typing error: StatusOperacaoRe**<span style="color:#FF0000">s</span>**pository is wrong, it should be StatusOperacaoRepository.

    See docs: <a class="postlink" href="http://www.aspnetboilerplate.com/Pages/Documents/Dependency-Injection#DocConventionalRegister">http://www.aspnetboilerplate.com/Pages/ ... alRegister</a>

    From document:

    "Naming conventions are very important here. For example you can change name of PersonAppService to MyPersonAppService or another name which contains 'PersonAppService' postfix since the IPersonAppService has this postfix. But you can not name your service as PeopleService. If you do it, it's not registered for IPersonAppService automatically (It's registered to DI framework but with self-registration, not with interface), so, you should manually register it if you want."

  • User Avatar
    0
    mayowa ogundele created

    Hello, I also have an issue related to the error above. I am trying to use the repository entity pattern, but i keep having the error above. The actual error is Can't create component 'Users.UserProfileAppService' as it has dependencies to be satisfied.

    'Users.UserProfileAppService' is waiting for the following dependencies:

    • Service 'Abp.Domain.Repositories.IRepository`1[[Users.UserProfile, AppMine.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' which was not registered.
    public class UserProfileAppService : IUserProfileAppService
        {
            private readonly IRepository&lt;UserProfile&gt; _userProfileRepository;
    
            public UserProfileAppService(IRepository&lt;UserProfile&gt; userProfileRepository)
            {
                _userProfileRepository = userProfileRepository;
            }
     }
    

    UserProfile inherits from Entity; IUserProfileAppService inherits from IApplicationService

  • User Avatar
    0
    hikalkan created
    Support Team

    Have you added UserProfile to your DbContext?

  • User Avatar
    0
    mayowa ogundele created

    I didnt add it to the DbContext, because it is supposed to be a virtual property of User.

  • User Avatar
    0
    hikalkan created
    Support Team

    Hmm.. that's why it's not created. Because ABP gets your DbContext and creates a repository for each DbSet in the Context. We may consider to create repository for derived types (<a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/issues/554">https://github.com/aspnetboilerplate/as ... issues/554</a>). For now, you can add your entity to DbContext (I advice it) or create a custom repository (it's also simple: <a class="postlink" href="http://www.aspnetboilerplate.com/Pages/Documents/EntityFramework-Integration#DocCustomRepositoryMethods">http://www.aspnetboilerplate.com/Pages/ ... oryMethods</a>)