I think what I'm looking for is something very simple, yet I am unable to find any examples.
I'd like to use Ninject to create an object by having Ninject call a factory method with a parameter specified and not injected during the actual request to instantiate the object:
Request for an object here:
StandardKernel.Get<ISomeInteface>(new Ninject.Parameters.Parameter("dataContext", dataContext, true));
And I'd like to map the ISomeInterface to a method that is expecting a value to be passed to it at runtime.
Mapping an interface here:
Kernel.Bind<ISomeInterface>().ToMethod(SomeObject.Create(--> `what do I put here?`));
Is this possible? If so, how do I properly map my interface?
Thanks!
ToMethod(ctx =>
SomeObject.Create(
(IDataContext)ctx.Parameters.Single(p =>p.Name == "dataContext")
.GetValue(ctx, null))
But you should rethink your design to avoid calling Get from anywhere else than your composite root.
Related
I'm setting up a Method call from a class
DATA: r_info TYPE REF TO zcl_sv_job_offline_ctrl.
CALL METHOD r_info->create
EXPORTING
is_data = lr_test_record.
And receiving the following errors:
CX_SY_REF_IS_INITAL
You are trying to access a component with a 'ZERO' object reference (points to nothing). Variable: "R_INFO".
Am I missing something?
You missed to create the object.
so you need to to:
create object r_info.
or
r_info = new zcl_sv_job_offline_ctrl( ).
or if there is a "factory method" ( what your 'create' method indicates )
r_info = zcl_sv_job_offline_ctrl=>create( is_data = lr_test_record ).
Your Exception tells you that the reference ( r_info ) is not connected with an object on the heap. So you need to do one of the above steps and then it should work. ( depending on your class )
Sorry, I don't have the rep to comment just yet...
I notice that your class is a Z so I'm wondering if you are trying to create a singleton class. In which case. Your 'Create' should be static. Your Constructor private and your Instance in a private attribute.
From the other comments, I agree, your question is missing some key details to provide an accurate answer.
If IO_DISPATCHER is part of the constructor and you are unable to pass a value, you need to dig a little deeper into the purpose of the class. See if you can give it what it wants. Try a 'where used' and check out the other usages of the class. You might find you are looking at the wrong class, or at least approaching from the wrong direction.
If create is some method on the class and it is not static then you will never get it to work until you create an instance of the class.
Another thought that comes to mind is that you might be in the right place and just doing the wrong thing. Check your globals to see if there is already an instance of the class and you are trying to access something via declaration as data rather than using the global instance??
All guess work without more details.
Thanks all.
The solution was simply to instantiate the parent classes (properly), enabled me to instantiate the class in question.
I am attempting to use the ToFactory extension for Ninject, but am running into a few problems.
If I have a constructor like this:
public ListenerReader(IDepen1 depen1, IDepen2 depen2, UdpClient client, DataReceiveModes dataReceiveMode, int receivePort)
{
}
And then I create a factory to automatically create the items like this:
public interface IListenerReaderFactory
{
ListenerReader CreateListenerReader(UdpClient client, DataReceiveModes dataReceiveMode, int receivePort);
}
I receive an activation error when I try to call the injected factory:
Error activating int
No matching bindings are available, and the type is not self-bindable.
It seems like Ninject does not like to inject primitive types in the factories. I have also seen this same error but with the string type in another factory?
If this does not work do I have to separate the parameters into a called method?
EDIT:
It appears that the type in question was being injected outside of the factory. Thus Ninject was trying to create bindings for the enum and int types which failed.
The problem was the factory was not being called and the type was being injected directly instead.
I am using Model-Glue/Coldspring for a new application and I thought I would throw CF9 ORM into the mix.
The only issue I am having right now is with populating an entity with an object. More or less the code below verifies that only one username can exist. There is some other logic that is not displayed.
My first thought was to using something like this:
var entity = entityload('UserAccount' ,{UserName=arguments.UserAccount.getUserName()},"true")
entity = arguments.UserAccount;
How ever this does not work the way that I expected. Is it even possible to populate an entity with an object or do I need to use the setters?
Not sure if this is what you're looking for. If you have...
component persistent="true" entityName="Foo"
{
property a;
property b;
}
You can pass a struct in the 2nd param to init the entity (added in CF9.0.1 I believe)
EntityNew("Foo", {a="1",b="2"});
To populate Foo with another object, you can use the Memento pattern, and implement a GetMemento() function to your object that returns a struct of all its properties.
EntityNew("Foo", bar.getMemento());
However, CF does NOT call your custom setters! If you want to set them using setters, you may add calls to the setters in your init() constructor, or use your MVC framework of choice to populate the bean. In Model-Glue, it is makeEventBean().
Update: Or... Here's hack...
EntityNew("Foo", DeserializeJSON(SerializeJSON(valueObject)));
Use this at your own risk. JSON might do weird things to your numbers and the 'yes','no','true','false' strings. :)
Is it even possible to populate an entity with an object or do I need to use the setters?
If you mean "Is it possible to create load an ORM Entity from an instance of that persistent CFC that already exists and has properties set?", then yes you can using EntityLoadByExample( object,[unique] )
entity = EntityLoadByExample( arguments.userAccount,true );
This assumes the userAccount CFC has been defined as persistent, and its username value has been set before being passed in (which seems to be the case in your situation).
Bear in mind that if any other properties have been set in the object you are passing, including empty strings, they will be used as filters to load the entity, so if they do not exactly match a record in your database, nothing will be loaded.
I'm fairly new to Ninject, but I have successfully managed to use it for DI using a custom provider.
The binding is initialised as follows
kernel = new StandardKernel();
kernel.Bind<IPatientRecordLocator>().ToProvider<PatientRecordLocatorProvider>();
and in the custom provider I call Activator.CreateInstance like so
protected override IPatientRecordLocator CreateInstance(IContext context)
{
var name = ConfigurationManager.AppSettings["PatientRecordLocator"];
var typeName = name.Split(',')[0];
var assemblyName = name.Split(',')[1];
return Activator.CreateInstance(assemblyName, typeName).Unwrap() as IPatientRecordLocator;
}
(yes, I am aware that there is no error handling, etc. in the code above :) )
and all this works like a charm.
Now, the problem I'm facing is when I introduce a new class that I wish to inject into instances of IPatientRecordLocator. The problem occurs when I add a constructor like the following to e.g. one of these classes
[Inject]
public MockPatientRecordLocator (IContactAdapter contactAdapter)
{
...
}
Then, for Activator.CreateInstance to work I also have to add a parameterless constructor to class MockPatientRecordLocator, i.e.
public MockPatientRecordLocator()
{
}
So, my question is: how can I make Ninject inject an instance of a class that implements IContactAdapter into e.g. MockPatientRecordLocator? I've tried method injection, but to no avail.
I forgot to explain that what I'm trying to achieve is a kind of chained injection where an instance of class PatientRecordSummary gets injected with an instance of MockPatientRecordLocator (using constructor injection) and said instance of MockPatientRecordLocator should get injected with an instance of IContactAdapter (again using constructor injection (if possible)). The first part of the chain works, the second doesn't.
Not bad for a first question!
You want to use the Bind(Type) overload to allow registration of stuff that you dont have statically available in the context of your Load() code - do the stuff you're doing in your provider (i.e., resolving the Type) up-front. This will allow Ninject to do the object instantiation (without any requirement for a default .ctor)
IIRC two or 3 of my most recent answers also touch on this discovery/loading stuff, and have examples that should be relevant to your case.
(And you wont need to resort to [Inject] attributes when you've gotten to remove things)
I have an object called Parameters that gets tossed from method to method down and up the call tree, across package boundaries. It has about fifty state variables. Each method might use one or two variables to control its output.
I think this is a bad idea, beacuse I can't easily see what a method needs to function, or even what might happen if with a certain combination of parameters for module Y which is totally unrelated to my current module.
What are some good techniques for decreasing coupling to this god object, or ideally eliminating it ?
public void ExporterExcelParFonds(ParametresExecution parametres)
{
ApplicationExcel appExcel = null;
LogTool.Instance.ExceptionSoulevee = false;
bool inclureReferences = parametres.inclureReferences;
bool inclureBornes = parametres.inclureBornes;
DateTime dateDebut = parametres.date;
DateTime dateFin = parametres.dateFin;
try
{
LogTool.Instance.AfficherMessage(Variables.msg_GenerationRapportPortefeuilleReference);
bool fichiersPreparesAvecSucces = PreparerFichiers(parametres, Sections.exportExcelParFonds);
if (!fichiersPreparesAvecSucces)
{
parametres.afficherRapportApresGeneration = false;
LogTool.Instance.ExceptionSoulevee = true;
}
else
{
The caller would do :
PortefeuillesReference pr = new PortefeuillesReference();
pr.ExporterExcelParFonds(parametres);
First, at the risk of stating the obvious: pass the parameters which are used by the methods, rather than the god object.
This, however, might lead to some methods needing huge amounts of parameters because they call other methods, which call other methods in turn, etcetera. That was probably the inspiration for putting everything in a god object. I'll give a simplified example of such a method with too many parameters; you'll have to imagine that "too many" == 3 here :-)
public void PrintFilteredReport(
Data data, FilterCriteria criteria, ReportFormat format)
{
var filteredData = Filter(data, criteria);
PrintReport(filteredData, format);
}
So the question is, how can we reduce the amount of parameters without resorting to a god object? The answer is to get rid of procedural programming and make good use of object oriented design. Objects can use each other without needing to know the parameters that were used to initialize their collaborators:
// dataFilter service object only needs to know the criteria
var dataFilter = new DataFilter(criteria);
// report printer service object only needs to know the format
var reportPrinter = new ReportPrinter(format);
// filteredReportPrinter service object is initialized with a
// dataFilter and a reportPrinter service, but it doesn't need
// to know which parameters those are using to do their job
var filteredReportPrinter = new FilteredReportPrinter(dataFilter, reportPrinter);
Now the FilteredReportPrinter.Print method can be implemented with only one parameter:
public void Print(data)
{
var filteredData = this.dataFilter.Filter(data);
this.reportPrinter.Print(filteredData);
}
Incidentally, this sort of separation of concerns and dependency injection is good for more than just eliminating parameters. If you access collaborator objects through interfaces, then that makes your class
very flexible: you can set up FilteredReportPrinter with any filter/printer implementation you can imagine
very testable: you can pass in mock collaborators with canned responses and verify that they were used correctly in a unit test
If all your methods are using the same Parameters class then maybe it should be a member variable of a class with the relevant methods in it, then you can pass Parameters into the constructor of this class, assign it to a member variable and all your methods can use it with having to pass it as a parameter.
A good way to start refactoring this god class is by splitting it up into smaller pieces. Find groups of properties that are related and break them out into their own class.
You can then revisit the methods that depend on Parameters and see if you can replace it with one of the smaller classes you created.
Hard to give a good solution without some code samples and real world situations.
It sounds like you are not applying object-oriented (OO) principles in your design. Since you mention the word "object" I presume you are working within some sort of OO paradigm. I recommend you convert your "call tree" into objects that model the problem you are solving. A "god object" is definitely something to avoid. I think you may be missing something fundamental... If you post some code examples I may be able to answer in more detail.
Query each client for their required parameters and inject them?
Example: each "object" that requires "parameters" is a "Client". Each "Client" exposes an interface through which a "Configuration Agent" queries the Client for its required parameters. The Configuration Agent then "injects" the parameters (and only those required by a Client).
For the parameters that dictate behavior, one can instantiate an object that exhibits the configured behavior. Then client classes simply use the instantiated object - neither the client nor the service have to know what the value of the parameter is. For instance for a parameter that tells where to read data from, have the FlatFileReader, XMLFileReader and DatabaseReader all inherit the same base class (or implement the same interface). Instantiate one of them base on the value of the parameter, then clients of the reader class just ask for data to the instantiated reader object without knowing if the data come from a file or from the DB.
To start you can break your big ParametresExecution class into several classes, one per package, which only hold the parameters for the package.
Another direction could be to pass the ParametresExecution object at construction time. You won't have to pass it around at every function call.
(I am assuming this is within a Java or .NET environment) Convert the class into a singleton. Add a static method called "getInstance()" or something similar to call to get the name-value bundle (and stop "tramping" it around -- see Ch. 10 of "Code Complete" book).
Now the hard part. Presumably, this is within a web app or some other non batch/single-thread environment. So, to get access to the right instance when the object is not really a true singleton, you have to hide selection logic inside of the static accessor.
In java, you can set up a "thread local" reference, and initialize it when each request or sub-task starts. Then, code the accessor in terms of that thread-local. I don't know if something analogous exists in .NET, but you can always fake it with a Dictionary (Hash, Map) which uses the current thread instance as the key.
It's a start... (there's always decomposition of the blob itself, but I built a framework that has a very similar semi-global value-store within it)