Is it possible to do implicit constructor injection in F# using Ninject? If so, how?
I tried to put the [<Inject>] attribute on the type definition, but I got back an error that it's invalid.
Here is what I tried:
[<Inject>]
type Blah(x : ISword) =
The Inject attribute is for Property setter injection only. Constructor injection is implicit. Just create your bindings and then make a kernel.Get<Blah>() and Blah is created using constructor injection.
The spec allows this as follows:
class-type-defn :=
type-name primary-constr-args_opt object-val_opt '=' class class-type-body end
where
primary-constr-args :=
attributes_opt accessopt (simple-pat, ... , simple-pat)
As a result, you just need to change your code to
type Blah [<Inject>](x : ISword) =
Here's Constructor Injection in F#:
type Foo(bar : IBar) =
// class members etc. here
Any library that requires you to slap an attribute on the type in order to understand that, is doing something wrong; pick another library.
Related
What is the syntax for creating a .Net object from java code (NObject) when the constructor of the .Net object has one or more parameters?
Thanks
The answer by erotavlas is correct although the syntax for classes is much simpler and can be done with a one-liner (https://www.javonet.com/java-devs/guides/creating-instance-calling-instance-methods/).
To create .NET object from Java you simply use:
NObject object = Javonet.New("Namespace.ClassName", params...);
Additional note if your class constructor has array parameter (of any type) you need to cast it to Object array.
int[] arg1;
Javonet.New("Namespace.ClassName", new Object[] {arg1})
Also, you can try new service that will create a strongly typed java wrapper for you (have a read here https://www.javonet.com/blog/more-about-javonet-io/)
I figured it out in case it wasn't obvious from the documentation
Add your reference to the dll using
Javonet.addReference()
Get the type (class name)
NType test = Javonet.getType("Namespace.Classname");
Call constructor with zero or more parameters
NObject obj = test.create(parameter1,parameter2, parameter3,.....etc);
I'd like to subclass the XMLUnit.NET CompareConstraint class in my F# code.
However, that class only has a single private constructor. If I try to inherit it, I get this compile error:
This 'inherit' declaration specifies the inherited type but no arguments. Consider supplying arguments, e.g. 'inherit BaseType(args)'.
Is there any way to inherit a class without a public constructor in F#?
This is not an F# limitation – it is not possible to inherit from a type with only private constructors in any .NET language.
Consider this program:
type
TMyClass<T: class> = class
public type
TClassOfT = class of T;
end;
begin
end.
This fails to compile at the declaration of TClassOfT with the error message:
E2021 Class type required
Can anyone explain why this is so? If I were to instantiate this class with, for instance TMyClass<TObject> then surely class of TObject would be meaningful. I constrained the generic parameter to be a class. So how can the compiler object that T is not a class type?
So far as I can tell, there is no reason for the compiler to reject this code. Thus, I believe that it is a design flaw and have submitted QC#121178.
I'm trying to write a property which uses generics:
type TMyClass = class
protected
function GetCountBy<T: Class>: Integer;
public
property CountBy<T: Class>: Integer read GetCountBy<T>;
end;
but the compile fails on the property declaration with the message 'Property CountBy does not exist in base class', and the red squiggle on the opening < of the property name.
Is there any way to achieve this?
Edit:
Here's my other use case, which is more complex but more real world:
property ItemsBy<T: Class>[Index: Integer]: T read GetItemsBy<T> write SetItemsBy<T>;
The function filters the contents of a list to return the Index'th item of the specified class.
Generic properties are not supported in Delphi. Only generic classes, or generic methods.
I can't find anything in the documentation that explicitly states that limitation. On the other hand the documentation only describes generic classes and generic methods. And the new language grammar to support generics also makes no mention of properties.
I'm not up to speed on generics but shouldn't the declaration be more like this
type TMyClass<T: class> = class
protected
function GetCountBy<T>: Integer;
public
property CountBy<T>: Integer read GetCountBy<T>;
end;
I would love to be able to code in Delphi this way, simply annotating a field:
type
TMyClass = class
private
[Inject]
Factory: ISomeFactory;
...
end;
or by attributing a setter
type
TMyClass = class
private
FFactory: ISomeFactory;
[Inject]
procedure SetFactory(const AFactory: ISomeFactory);
...
public
property Factory: ISomeFactory read FFactory write SetFactory;
end;
The background: I am moving old code to a service-oriented architecture and find that referencing the service layer always leads to constructs like
DataModule1.ServiceLayerInstance1.SubSystemN.InvokeSomething(Params, ...);
which could be much shorter like
type
Form1 = class(TForm1)
private
[Inject]
SubsystemN: ISubsystemN;
...
end;
...
SubsystemN.InvokeSomething(Params, ...);
Yes, there is. The Delphi Spring Framework
http://www.spring4d.com/
does precisely this. It has an [Inject] attribute.
One caveat -- to use it, you need to include the Spring unit in your code where the attribute is defined. Otherwise, the compiler will ignore the attribute.
You can achieve this goal with the Emballo OpenSource project.
See the project on Google Code:
http://code.google.com/p/emballo/wiki/WhyDependencyInjection