Ninject: More than one matching bindings are available - ninject

I have a dependency with parameters constructor. When I call the action more than 1x, it show this error:
Error activating IValidationPurchaseService
More than one matching bindings are available.
Activation path:
1) Request for IValidationPurchaseService
Suggestions:
1) Ensure that you have defined a binding for IValidationPurchaseService only once.
public ActionResult Detalhes(string regionUrl, string discountUrl, DetalhesModel detalhesModel)
{
var validationPurchaseDTO = new ValidationPurchaseDTO {...}
KernelFactory.Kernel.Bind<IValidationPurchaseService>().To<ValidationPurchaseService>()
.WithConstructorArgument("validationPurchaseDTO", validationPurchaseDTO)
.WithConstructorArgument("confirmPayment", true);
this.ValidationPurchaseService = KernelFactory.Kernel.Get<IValidationPurchaseService>();
...
}

I'm not sure what are you trying to achieve by the code you cited. The error is raised because you bind the same service more than once, so when you are trying to resolve it it can't choose one (identical) binding over another. This is not how DI Container is supposed to be operated. In your example you are not getting advantage of your DI at all. You can replace your code:
KernelFactory.Kernel.Bind<IValidationPurchaseService>().To<ValidationPurchaseService>()
.WithConstructorArgument("validationPurchaseDTO", validationPurchaseDTO)
.WithConstructorArgument("confirmPayment", true);
this.ValidationPurchaseService = KernelFactory.Kernel.Get<IValidationPurchaseService>();
With this:
this.ValidationPurchaseService = new ValidationPurchaseService(validationPurchaseDTO:validationPurchaseDTO, confirmPayment:true)
If you could explain what you are trying to achieve by using ninject in this scenario the community will be able to assist further.

Your KernelFactory probably returns the same kernel (singleton) on each successive call to the controller. Which is why you add a similar binding every time you hit the URL that activates this controller. So it probably works the first time and starts failing after the second time.

Related

Dynamic model attribute with SAILSJS

My use case needs me to use Dynamic Model attributes with my Sails.Js project and all of my methods fail. First I tried to call model1 method from model2 but it doesn't works. I also tried to use global variables but this fails too because, the global is set after the load of the application, and finaly I called model1Controller from the model2 but it still not working.
This is the mothod in my model2Controller
getbyTable:function(req,res){
let field = Field.find({fTable:req.param('tableName')});
field.exec(function(err, response) {
if(err) {
res.status(500);
return res.view('500', {data: err});
}
//res.json(response);
return response;
});
},
And this is my model2
'use strict';
const fieldController = require('../controllers/Model1Controller');
const donnees = fieldController.getbyTable('person');
module.exports={
}
When run it fires as error that req.param is not a function.
Need help!!! Thanks.
This looks like an interesting way to organize - I'd be curious to see how successful a project could be without Model attributes set in stone.
I can see a few specific errors in your code, maybe seeing them will help you move forward.
From your model2 you invoke getbyTable('person') with a string argument - but all controller methods are really intended to have reqest/response arguments (as in the definition getbyTable(req, res). Directly invoking a controller method is a bit unusual - if you ever did it, I'd expect to pass along a request and response from some other controller method.
Inside getbyTable, you try to return the response, but the response is only defined inside the exec callback. The response would be an array of objects fetched from your database - if that's what you need, you can't return them directly since database calls are async.
Your controller should probably do something with res in all logical branches, such as res.json, res.send, etc.
It's a bit hard to see exactly what you're trying to achieve, so maybe if you could explain the goal I could have some more relevant advice. For now, I could say that you might want to consider putting some code inside a service rather than a controller. Create file /api/services/MyService.js and use it to export a method that can be called from your model2 (you can require the service just like the controller). Keep the controller methods strictly for handling requests.
Good luck.

Activiti BPMN - How to pass username in variables/expression who have completed task?

I am very new to Activiti BPMN. I am creating a flow diagram in activiti. I m looking for how username (who has completed the task) can be pass into shell task arguments. so that I can fetch and save in db that user who has completed that task.
Any Help would be highly appreciated.
Thanks in advance...
Here's something I prepared for Java developers based on I think a blog post I saw
edit: https://community.alfresco.com/thread/224336-result-variable-in-javadelegate
RESULT VARIABLE
Option (1) – use expression language (EL) in the XML
<serviceTask id="serviceTask"
activiti:expression="#{myService.toUpperCase(myVar)}"
activiti:resultVariable="myVar" />
Java
public class MyService {
public String toUpperCase(String val) {
return val.toUpperCase();
}
}
The returned String is assigned to activiti:resultVariable
HACKING THE DATA MODEL DIRECTLY
Option (2) – use the execution environment
Java
public class MyService implements JavaDelegate {
public void execute(DelegateExecution execution) throws Exception {
String myVar = (String) execution.getVariable("myVar");
execution.setVariable("myVar", myVar.toUpperCase());
}
}
By contrast here we are being passed an ‘execution’, and we are pulling values out of it and twiddling them and putting them back.
This is somewhat analogous to a Servlet taking values we are passed in the HTMLRequest and then based on them doing different things in the response. (A stronger analogy would be a servlet Filter)
So in your particular instance (depnding on how you are invoking the shell script) using the Expression Language (EL) might be simplest and easiest.
Of course the value you want to pass has to be one that the process knows about (otherwise how can it pass a value it doesn't have a variable for?)
Hope that helps. :D
Usually in BPM engines you have a way to hook out listener to these kind of events. In Activiti if you are embedding it inside your service you can add an extra EventListener and then record the taskCompleted events which will contain the current logged in user.
https://www.activiti.org/userguide/#eventDispatcher
Hope this helps.
I have used activiti:taskListener from activiti app you need to configure below properties
1. I changed properties in task listener.
2. I used java script variable for holding task.assignee value.
Code Snip:-

Output caching with location=server not working

I have implemented outputcaching on Action method of controller with
[OutputCache(Duration = 60, VaryByParam = "ID", VaryByHeader="User-Agent", Location = System.Web.UI.OutputCacheLocation.Server)]
public ActionResult MyAction(int ID)
{
_logger.Error("call-" + ID);
}
and I have made log entry within this action. So, My problem is Output caching with location=Server calls this action method every time. It should not call every-time.
So, what's the problem with this?
When I changed Caching location i.e location=Client then only first time it calls the method. Then afterwards action method not called.
Are you trying output caching on the ChildAction? I know you have not written ChildAction attribute in your question but just asking for confirmation ? If it is then you can't use output caching on which are not Child Actions. You need to use this caching plugin if you want to use output caching without child action.

Autofac SingleInstance not working

I am trying to get a Singleton instance working with Autofac. I'm kind of doing a quasi-mvvm type thing with Winforms, just an experiment so don't get to hung up on that. But I am trying you have my model be a single instance with a reference in a command (ICommand here is not the WPF variety):
I have the following setup of a container:
var cb = new ContainerBuilder();
cb.RegisterType<CalculateCommissionCommand>().As<ICommand<TradeEntry>>().SingleInstance();
cb.RegisterType<CalculationsModel>().As<ICalculationsModel>().SingleInstance();
cb.Register(c => new CalculationsView() { Model = c.Resolve<ICalculationsModel>() }).SingleInstance();
cb.Build();
Now the Command takes an ICalculationsModel as a constructor parameter. However, when I set a value in the Model being passed to the Command, that value does not appear within the model that has already been set withing the CalculationsView. It seems that the command and the view are being passed different instances of the CalculationsModel despite the "singleInstance" method being called. Am I missing something? Why is this happening?
We hit a similar problem today and this seems to be the only post where this question is asked, so I thought I'd share our experience in the hopes it helps someone out. In the end it was something right in front of our eyes and of course they're usually the hardest problems to solve :-).
In our scenario, we were:
Registering a specific implementation of a configuration provider
Auto-registering certain types within an assembly.
Something along these lines:
var cb = new ContainerBuilder();
cb.RegisterType<FileBasedConfigurationProvider>()
.As<IConfigurationProvider>()
.SingleInstance();
cb.RegisterAssemblyTypes(typeof(MailProvider).Assembly)
.Where(t => !t.IsAbstract && t.Name.EndsWith("Provider"))
.AsImplementedInterfaces();
Stupidly, we didn't think about/realise that the FileBasedConfigurationProvider was in the same assembly as the MailProvider, so the second registration call basically overwrote the first one; hence, SingleInstance "wasn't working".
Hope that helps someone else out!
It's not clear from your code how you are storing/using the container. It is likely you have created multiple containers.
In my case the problem was that the parameter to the method generating the second instance was defined as the class instead of the interface
i.e.
SomeMethod(ClassName parameter)
instead of
SomeMethod(**I**ClassName parameter)
Obvious mistake, but took a few minutes to see it.
In my case I had two registrations for a class for different interfaces declaring that each was single instance. I assumed there would be a single instance of the class... no there's a single instance for each registration.
e.g
builder.RegisterType<MyClass>().As<IMyFirstInterface>().SingleInstance(); // 1st instance
builder.RegisterType<MyClass>().As<IMySecondInterface>().SingleInstance(); // 2nd instance
The correct way to do this was...
builder
.RegisterType<MyClass>()
.As<IMyFirstInterface>()
.As<IMySecondInterface>()
.SingleInstance();

How do I utilize a named instance within the ObjectFactory.Initialize call for StructureMap?

I am trying to do the following bootstrapping:
x.For(Of IErrorLogger).Use(Of ErrorLogger.SQLErrorLogger)().
Ctor(Of IErrorLogger)("backupErrorLogger").Is(ObjectFactory.GetNamedInstance(Of IErrorLogger)("Disk"))
x.For(Of IErrorLogger).Add(
Function()
Return New ErrorLogger.DiskErrorLogger(
CreateErrorFileName(ServerMapPath(GetAppSetting("ErrorLogFolder"))))
End Function).Named("Disk")
But it shows this error:
StructureMap Exception Code: 200
Could not find an Instance named "Disk" for PluginType Logging.IErrorLogger
I sort of understand why this is happening.. the question is, how do I utilize a named instance within the registry? Maybe something like lazy initialization for the ctor argument for the SQLErrorLogger? I am not sure how to make it happen.
Thanks in advance for any help you can provide.
I found the correct way to do it in the latest version (2.6.1) of StructureMap:
x.For(Of IErrorLogger).Use(Of ErrorLogger.SQLErrorLogger)().
Ctor(Of IErrorLogger)("backupErrorLogger").Is(
Function(c) c.ConstructedBy(Function() ObjectFactory.GetNamedInstance(Of IErrorLogger)("Disk"))
)
x.For(Of IErrorLogger).Add(Function() _
New ErrorLogger.DiskErrorLogger(
CreateErrorFileName(ServerMapPath(GetAppSetting("ErrorLogFolder"))))
).Named("Disk")
Notice for the Is method of Ctor, we need to provide a func(IContext), and use the IContext.ConstructedBy(Func()) to call ObjectFactory.Get... to successfully register the IErrorLogger in this case.
This is the only way to do it as far as I know. The other Icontext methods such as IsThis and Instance will only work with already registered type.
Your problem is that you are trying to access the Container before it's configured. In order to make structuremap evaluate the object resolution after the configuration you need to provide a lambda to the Is function. The lambda will be evaluated when trying to resolve the type registered.
x.[For](Of ILogger)().Add(Of SqlLogger)().Ctor(Of ILogger)("backupErrorLogger")_
.[Is](Function(context) context.GetInstance(Of ILogger)("Disk"))
x.[For](Of ILogger)().Add(Of DiskLogger)().Ctor(Of String)("errorFileName")_
.[Is](CreateErrorFileName(ServerMapPath(GetAppSetting("ErrorLogFolder"))))_
.Named("Disk")
Disclaimer: I'm not completely up-to-date with the lambda syntax in VB.NET, but I hope I got it right.
Edit:
The working C# version of this I tried myself before posting was this:
ObjectFactory.Initialize(i =>
{
i.For<ILogger>().Add<SqlLogger>()
.Ctor<ILogger>("backup").Is(
c => c.GetInstance<ILogger>("disk"))
.Named("sql");
i.For<ILogger>().Add<DiskLogger>().Named("disk");
});
var logger = ObjectFactory.GetNamedInstance<ILogger>("sql");