Base solution for your next web application
Open Closed

Common code for several Appservices goes where? #2071


User avatar
0
bubba created

I'm having trouble understanding where to put code that is common for several appservices. Since I know it is bad to let one appservice use another appservice where can I put the code? And before you answer you need to know that this code is only making operations on an object that exists in Session and that is not defined anywhere in Core.

Right now I have put the code in a static helper class but it's not pretty. I'm sending in the domainservices I use as parameters to the static function and there are sometimes many of them.

So to repeat my question; I'm doing operations (using many domainservices) on a DTO that lives in Session; How do I best do this from several appservices without having to repeat my code?


4 Answer(s)
  • User Avatar
    0
    bubba created

    An example of such code could be:

    // ci is the DTO and this code is used by several appservices. Where to put it so I can follow "DRY" and without letting one appservice reference another appservice? 
    
    ci.Price = await _exchangeRatesManager.GetPriceInCurrentCurrency(ci.Price, geo.Currency); 
    // _exchangeRatesManager is a domain service
    ci.Tax = await _taxManager.GetTax(geo.Region, ci.Price, ci.TaxClass);
    // _taxManager is a domain service
    ci.xx = await ... 
    ...
    
  • User Avatar
    0
    bubba created

    Anyone?

  • User Avatar
    0
    gpcaretti created

    Why you say "It is bad to let one appservice use another appservice"?

    Anyhow, I put some of this code in MyAppServiceBase, Some in Manager classes and some in Helpers:

    public class AuctionAppService : MyNewHouseAppServiceBase, IAuctionAppService {
    	private readonly IAuctionRepo _auctionsRepo;
        public UserManager UserManager { get; set; }
    	
    	...
    }
    
    public abstract class MyNewHouseAppServiceBase : ApplicationService {
    	public TenantManager TenantManager { get; set; }
    	public IEventBus EventBus { get; set; }
    
    	protected async virtual Task<User> MyCommonUsefulMethodAsync(...) {
    		...
    		return user;
    	}
    	...
    }
    
    public class UserManager : AbpUserManager<Role, User> {
    
    	public UserManager(
    		UserStore userStore,
    		RoleManager roleManager,
    		IPermissionManager permissionManager,
    		IUnitOfWorkManager unitOfWorkManager,
    		ICacheManager cacheManager,
    		IRepository<OrganizationUnit, long> organizationUnitRepository,
    		IRepository<UserOrganizationUnit, long> userOrganizationUnitRepository,
    		IOrganizationUnitSettings organizationUnitSettings,
    		ILocalizationManager localizationManager,
    		ISettingManager settingManager,
    		IdentityEmailMessageService emailService,
    		IUserTokenProviderAccessor userTokenProviderAccessor)
    		: base(
    				userStore,
    				roleManager,
    				permissionManager,
    				unitOfWorkManager,
    				cacheManager,
    				organizationUnitRepository,
    				userOrganizationUnitRepository,
    				organizationUnitSettings,
    				localizationManager,
    				emailService,
    				settingManager,
    				userTokenProviderAccessor) {
    
    	}
    
    	...
    }
    
  • User Avatar
    0
    bubba created

    Thank you for your reply.

    This forum post told me that it was bad: #1028@04dacffb-ff73-44de-bd9a-d17e1b6edf03

    I actually ignored that advice at first and let my appservices use each other as needed, but when I had a controller use 2 appservices which in turn used eachother I got a circular reference error.

    Spreading the common code into baseclass, managers and helpers works, but it also works with using just helpers like I already do.

    The thing is I would like to know the best practise way. So all of you gurus out there feel free to join in ;)