is it possible to use the default resource provider that uses .resx files in the application but uses an SqlResourceProvider in a sub folder?
seems like the only one used is the one configured in web.config of the root?
any idea ?
I needed something similar, returning a custom ResourceProvider for specific classkeys, but then fallback to default resource providers otherwise.
I created a custom ResourceProviderFactory that returns my custom resource provider when requested, but otherwise returns null, which appears to cause the default provider to be used instead.
[DesignTimeResourceProviderFactory(typeof(CustomizedResourceProviderDesignTimeFactory))]
public class CustomizedResourceProviderFactory : ResourceProviderFactory
{
public override IResourceProvider CreateGlobalResourceProvider(string classKey)
{
if (classKey == "MyCustomResourceClass")
{
return new CustomizedResourceProvider(classKey);
}
else
{
return null;
}
}
// etc.
}
Related
In Shopware 6, I want to call a backend (/admin) API controller from a backend / admin page using JavaScript. What is the correct way to use a relative path, probably with a built-in getter function?
Fetching /api/v1 only works if the shop is on /, but not when it is in a sub-folder.
fetch('/api/v1/my-plugin/my-custom-action', ...)
The best practice would be to write your own JS service that handles communication with your api endpoint.
We have an abstract ApiService class, you can inherit from. You can take a look at the CalculatePriceApiService for an example in the platform.
For you an implementation might look like this:
class MyPluginApiService extends ApiService {
constructor(httpClient, loginService, apiEndpoint = 'my-plugin') {
super(httpClient, loginService, apiEndpoint);
this.name = 'myPluginService';
}
myCustomAction() {
return this.httpClient
.get('my-custom-action', {
headers: this.getBasicHeaders()
})
.then((response) => {
return ApiService.handleResponse(response);
});
}
}
Notice that your api service is preconfigured to talk to your my-plugin endpoint, in the first line of the constructor, which means in all the following request you make you can use the relative route path.
Keep also in mind that the abstract ApiService will take care of resolving the configuratuion used for the Requests. Especially this means the ApiService will use the right BaseDomain including subfolders and it will automatically use an apiVersion that is supported by your shopware version. This means the apiVersion the ApiService uses in the route will increase every time a new api version is available, that means you need to work with wildcards in your backend route annotations for the api version.
Lastly keep in mind you need to register that service. That is documented here.
For you this might look like this:
Shopware.Application.addServiceProvider('myPluginService', container => {
const initContainer = Shopware.Application.getContainer('init');
return new MyPluginApiService(initContainer.httpClient, Shopware.Service('loginService'));
});
If you are talking about custom action that you implemented, you need to define route (use annotation) and register controller in routes.xml in your Resources\config\routes.xml.
Please follow that documentation
https://docs.shopware.com/en/shopware-platform-dev-en/how-to/api-controller
I've got two hosted services in my web service: Domain and ComplianceService. ComplianceService needs to reference data and methods in Domain, like so:
public ComplianceService(ILogger<ComplianceService> logger, Domain domain, IRuleRepository ruleRepository)
{
// Initialize the service.
this.logger = logger;
this.domain = domain;
this.ruleRepository = ruleRepository;
}
My initialization in startup.cs looks like this:
// Add the dependencies.
serviceCollection.AddSingleton<RulesActivator>()
.AddSingleton<Accruals>()
.AddSingleton<IRuleRepository, ComplianceRuleRepository>()
.AddSingleton<IViolation, Violation>();
// Add the hosted services.
serviceCollection.AddHostedService<Domain>();
serviceCollection.AddHostedService<ComplianceService>();
When I try to run this, I get this message:
System.InvalidOperationException: 'Unable to resolve service for type 'ThetaRex.OpenBook.ServerDomain.Domain' while attempting to activate 'ThetaRex.OpenBook.WebApi.ComplianceService'.'
If I add Domain to the IoC, like this:
serviceCollection.AddSingleton<Domain>()
.AddSingleton<RulesActivator>()
.AddSingleton<Accruals>()
.AddSingleton<IRuleRepository, ComplianceRuleRepository>()
.AddSingleton<IViolation, Violation>();
It runs, but I get two copies of Domain. I can force it to work like this:
// Add the hosted services.
serviceCollection.AddHostedService(sp => sp.GetRequiredService<Domain>());
if (this.Configuration.GetValue<bool>("ComplianceEnabled"))
{
serviceCollection.AddHostedService<ComplianceService>();
}
But this seems really clumsy and counterintuitive. How come the AddHostedService can instantiate ComplianceService, but can't instantiate the dependent service?
How ImageSharp work with Dynamic Images loaded from Database?
Here my controller which get image file:
public async Task<FileResult> GetPhoto([FromQuery] GetFileAttachementInputAsync input)
{
var file = await filesAttachementAppService
.GetFileAsync(new GetFileAttachementInputAsync() { FileId = input.FileId })
.ConfigureAwait(false);
return file != null
? File(new MemoryStream(file.FileDto.FileContent), file.FileDto.ContentType, file.FileDto.FileName)
: null;
}
And this my Html call:
<img src="/PropertyAdministration/GetPhoto?FileId=#item.MainPhotoId&width=554&height=360" alt="" />
I am using ImageSharp as following:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddImageSharp();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env,ILoggerFactory loggerFactory)
{
app.UseImageSharp();
}
What I am missing here to make this working?
You're not using the middleware nor the services that provide images to the middleware.
For the middleware to work it needs to be able capture an image request. With the default installation this is done by matching the request to an image source in your physical file system in wwwroot.
In your code though you've created an isolated action result returning a stream containing your image which the middleware has no awareness of.
Disclaimer, the following is based on the latest developer build 1.0.0-dev000131 and though unlikely to change could potentially change before final release.
https://www.myget.org/feed/sixlabors/package/nuget/SixLabors.ImageSharp.Web/1.0.0-dev000131
In order to provide images from a custom source you will need to create your own implementation of the IImageProvider and IImageResolver you can use examples in the source to base your implementation from.
Once implemented you will need to register the implementations via dependency injection. This needs to use a more fine grained registration since you are no longer using the defaults.
// Fine-grain control adding the default options and configure all other services. Setting all services is required.
services.AddImageSharpCore()
.SetRequestParser<QueryCollectionRequestParser>()
.SetBufferManager<PooledBufferManager>()
.SetMemoryAllocatorFromMiddlewareOptions()
.SetCacheHash<CacheHash>()
.AddProvider<PhysicalFileSystemProvider>()
/// Add your provider here via AddProvider<T>().
.AddProvider<PhysicalFileSystemProvider>()
.AddProcessor<ResizeWebProcessor>()
.AddProcessor<FormatWebProcessor>()
.AddProcessor<BackgroundColorWebProcessor>();
You should then be able to remove your action result completely and use the IImageProvider and IImageResolver combination to identify the request and return the image.
in my wicket application settings I wish to mount a username parameter on the root like
mountPage (Profile.class, "/${username}") similar to how twitter maps the usernames to its accounts. In wicket this seems to crash the resource location algorithm. In the sense that all css, js files now load with 404.
Is there a work around this?
The code should look like: mountPage (Profile.class, "/${username}"). Note the $ that I've added. This means the named path parameter is mandatory.
Please give more details about the problem if this doesn't solve the issue.
Thanks to martin-g. Override the MountMapper with set the url segments to 1 so it doesn't map to other resources.
public class UsernameMountUrlMapper extends MountedMapper {
public UsernameMountUrlMapper(String mountPath,
Class<? extends IRequestablePage> pageClass) {
super(mountPath, pageClass);
}
#Override
protected boolean urlStartsWithMountedSegments(Url url) {
return url.getSegments().size() == 1 && !url.getPath().equals("favicon.ico") && !url.getPath().equals("oops") && !url.getPath().equals("Index");
}
}
I have below directory structure -
rootFolder
---CFC (contains all cfc file)
---SERVICES (contains all service file)
application.cfc
I have created one service named (userService.cfc) which have the below script
import services.userService;
component accessors="true" alias="services.userService"
{
remote userService function init()
{
return This;
}
remote any function getUser()
{
var userObj = new cfc.sessionUser();
return userObj;
}
}
If i call this service from inside the application, this is working fine
Again if i am trying to call it from outside the application, need to change this statement as below and again it is working fine.
import rootFolderName.services.userService;
component accessors="true" alias="rootFolderName.services.userService"
{
remote userServicefunction init()
{
return This;
}
remote any function getUser()
{
var userObj = new rootFolderName.cfc.sessionUser();
return userObj;
}
}
But If i put this code on another rootFolder suppose on "rootFolderName1" name i have to changed all the place where i used the rootFolderName. I got one solution by CFADMIN folder mapping on server level. but i want it on application level.
Can we configure it on Application.cfc? I have used Mappings also but that is not working.
Actually i have two separate application one flex application which is trying to access the second application services remotely. second application have cfc and sevices.
Please help on this.
I would review Ben Nadel's post on the use of ExpandPath() in writing app level CF mappings
http://www.bennadel.com/blog/2519-ExpandPath-Works-With-ColdFusion-s-Per-Application-Mappings.htm