Base solution for your next web application

Activities of "Astech"

We have a custom repository that we would like to use everywhere. However, when we try to change a repository that is being passed to a base class we are having issues. Please see below as an example in LoginManager:

public class LogInManager : AbpLogInManager<Tenant, Role, User>
{
    public LogInManager(IOurCustomRepository<Tenant> tenantRepository) 
                                        : base(tenantRepository)
    {
        ...
    }
}

This results in a compile time error of

Argument 3: cannot convert from 'OurProject.Repositories.IOurCustomRepository<OurProject.MultiTenancy.Tenant>' to 'Abp.Domain.Repositories.IRepository<OurProject.MultiTenancy.Tenant>'

We have also tried casting the repository when passed to base:

public class LogInManager : AbpLogInManager<Tenant, Role, User>
{
    public LogInManager(IOurCustomRepository<Tenant> tenantRepository) 
                                        : base((IRepository<Tenant>)tenantRepository)
    {
        ...
    }
}

This allows the code to build but results in the following runtime error:

ComponentActivator: could not instantiate OurProject.Authorization.LogInManager
 ---> System.InvalidCastException: Unable to cast object of type 'OurProject.EntityFrameworkCore.Repositories.OurCustomRepository`1[OurProject.MultiTenancy.Tenant]' to type 'Abp.Domain.Repositories.IRepository`1[OurProject.MultiTenancy.Tenant]'.

How can we use our custom repository in this way while still satifying the base? I am aware that we can change the registration of IRepository so that a different implementation is used via Dependency Injection however we wish to specify our own custom repository in this way.

It's important to add that our custom repository does inherit from IRepository:

public interface IOurCustomRepository<TEntity, TPrimaryKey> : IRepository<TEntity, TPrimaryKey> where TEntity : class, IEntity<TPrimaryKey>

This is why we believe this should be possible?

Thank you

Many thanks m.aliozkaya

This has resolved the issue. To help anyone else, this is the complete code segment for unit testing an app service that utilies SignalR:

var fakeDocumentHub = Substitute.For&lt;IHubContext&lt;DocumentHub&gt;>();
LocalIocManager.IocContainer.Register(Component.For&lt;IHubContext&lt;DocumentHub&gt;>().Instance(fakeDocumentHub).IsDefault());
var _documentsAppService = Resolve&lt;IDocumentsAppService&gt;();

Do this to get the service instance instead of using Dependency Injection in the unit test class itself.

Thanks again m.aliozkaya

Seems to be an issue when trying to write & run tests (in the .Test project), that access services that use a hub

I'm assuming the startup.cs from the MVC project does not get run when the tests run so how can we ensure these dependencies are registered within the .Test project in the same way they are within the .Mvc project like below:

app.UseEndpoints(endpoints =>
        {
            endpoints.MapHub<AbpCommonHub>("/signalr");
            endpoints.MapHub<ChatHub>("/signalr-chat");
            endpoints.MapHub<AgendaHub>("/signalr-agenda");
            endpoints.MapHub<MinuteHub>("/signalr-minute");
            endpoints.MapHub<DocumentHub>("/signalr-document-conversion");
        });

There appears to be no startup.cs file in the .Test project to try the same code. Trying to register the Hub in the same way as we register services in the test project:

public Security_Tests()
{
    _documentHub = Resolve&lt;IHubContext&lt;DocumentHub&gt;>();
    _documentsAppService = Resolve&lt;IDocumentsAppService&gt;(); // Service that uses the DocumentHub
}

Results in:

Abp.AbpException : Can not register IHubContext`1. It should be a non-abstract class. If not, it should be registered before.

Many thanks

Hi,

using Microsoft.AspNetCore.SignalR;

namespace Congresso.Documents
{
    public class DocumentHub : Hub
    {
    }
}

I did check the link to ensure that the necessary packages are also installed.

Hi,

Yes I already have it added in my startup. The other ones don't seem to be erroring.

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapHub&lt;AbpCommonHub&gt;("/signalr");
            endpoints.MapHub&lt;ChatHub&gt;("/signalr-chat");
            endpoints.MapHub&lt;AgendaHub&gt;("/signalr-agenda");
            endpoints.MapHub&lt;MinuteHub&gt;("/signalr-minute");
            endpoints.MapHub&lt;DocumentHub&gt;("/signalr-document-conversion");
        });

Hi, I have been getting the following error in my dev azure pipeline.

'Congresso.Documents.DocumentManager' is waiting for the following dependencies:

Service 'Microsoft.AspNetCore.SignalR.IHubContext`1[[Congresso.Documents.DocumentHub, Congresso.Core, Version=12.0.0.0, Culture=neutral, PublicKeyToken=null]]' which was not registered.

at Castle.MicroKernel.Handlers.DefaultHandler.AssertNotWaitingForDependency() at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden) at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.ResolveFromKernelByType(CreationContext context, ComponentModel model, DependencyModel dependency) at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateConstructorArguments(ConstructorCandidate constructor, CreationContext context) at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate(CreationContext context) at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context) at Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden) at Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden) at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.ResolveFromKernelByType(CreationContext context, ComponentModel model, DependencyModel dependency) at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateConstructorArguments(ConstructorCandidate constructor, CreationContext context) at Castle.Windsor.MsDependencyInjection.MsScopedLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden) at Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, Arguments additionalArguments, IReleasePolicy policy, Boolean ignoreParentContext) at Castle.Windsor.MsDependencyInjection.ScopedWindsorServiceProvider.GetServiceInternal(Type serviceType, Boolean isOptional) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.AbpZeroIdentityBuilderExtensions.<>c__DisplayClass0_01.&lt;AddAbpTenantManager&gt;b__0(IServiceProvider provider) at Castle.MicroKernel.ComponentActivator.FactoryMethodActivator1.Instantiate(CreationContext context) at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context) at Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden) at Castle.Windsor.MsDependencyInjection.MsScopedLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden) at Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, Arguments additionalArguments, IReleasePolicy policy, Boolean ignoreParentContext) at Abp.Events.Bus.EventBus.TriggerHandlingException(IEventHandlerFactory handlerFactory, Type eventType, IEventData eventData, List`1 exceptions) at Abp.Events.Bus.EventBus.Trigger(Type eventType, Object eventSource, IEventData eventData) at Abp.Events.Bus.Entities.EntityChangeEventHelper.TriggerEventWithEntity(Type genericEventType, Object entity, Boolean triggerInCurrentUnitOfWork) at Abp.Events.Bus.Ent

[AbpAuthorize] public class DocumentManager : CongressoDomainServiceBase, IDocumentManager {

private readonly IHubContext&lt;DocumentHub&gt; _documentHub;

public DocumentManager(
    IHubContext&lt;DocumentHub&gt; documentHub,
   )
{
    _documentHub = documentHub;
}


public class DocumentHub : Hub
{
}

}

Any suggestions?

Thanks!

Is there any reason why we could not consolidate there attributes and just have one for system wide authorization? Or is it necessary to use a different one in the MVC project to the application service?

Thanks

Hi,

I think you can directly use an if statement instead of combaning strings.

Could you give an example?

I'm trying to access a string from this object property:

"#if(" + (IsGranted("#=EntitySearch.ViewPermissionName#")).ToString().ToLower() + "){#" +

But I'm getting the following error as it's trying to search for the literal string instead of the property.

Abp.AbpException: There is no permission with name: #=EntitySearch.ViewPermissionName#

This works fine so I'm wondering if it's the IsGranted wrapper breaking it?

"#=EditModalButtonTemplate('EntitySearch.EditModalFunctionName', EntitySearch.Id)#"

The full grid:

                    @(Html.Kendo().Grid&lt;SearchViewModel&gt;().Name("EntitySearchList")
                        .DataSource(dataSource => dataSource
                            .Custom()
                            .Transport(transport =>  { transport.Read(read => read.Url(@Url.Action("Search_Read", "Searches")).DataType("json").Data("additionalData")); })
                            .Schema(schema => { schema.Model(m => m.Id("EntitySearchModel.Id")); schema.Data("Result.Result.Data").Total("Result.Result.Total"); })
                        )
                        .Columns(columns =>
                        {
                            columns.Bound(p => p.EntitySearch.Id).Title(" ").Filterable(false).Sortable(false).IncludeInMenu(false).HtmlAttributes(new { @class = "actions-column-cell" }).ClientTemplate(

                            "#if(" + (IsGranted("#=EntitySearch.ViewPermissionName#")).ToString().ToLower() + "){#" +

                            "#=ViewLinkButtonTemplate('" + @Url.Action("EntitySearch.ControllerViewFunctionName", "EntitySearch.ControllerName") + "', EntitySearch.Id" + ")#" +

                            "#}" +

                            "#=EditModalButtonTemplate('EntitySearch.EditModalFunctionName', EntitySearch.Id)#" +

                            "#=HistoryModalButtonTemplate(EntitySearch.Id, EntitySearch.Name, '" + @EntityTypeFullNames.Team.ToString() + "')#");

                            columns.Bound(p => p.EntitySearch.Id).IncludeInMenu(false);
                            columns.Bound(p => p.EntitySearch.SearchTypeDisplayName).IncludeInMenu(false);
                            columns.Bound(p => p.EntitySearch.Name).IncludeInMenu(false);
                        })
                        .Pageable()
                        .Events(events => events.DataBound("onDataBound"))
                        .NoRecords(x => x.Template("&lt;div class=&#39;empty-grid&#39;&gt;" + string.Format(@L("NoSomethingFound"),@L("CompletedActions").ToLower()) + "&lt;/div&gt;"))

                    )

Yes both the Id of the parent and child match

Showing 1 to 10 of 78 entries