Can I get an InstanceMirror of a class without using any constructor in Dart? - dart

Can I get an InstanceMirror without using any constructor in Dart?
More precisely: I have a class with or without any special constructor, yet I'd like to get an InstanceMirror without having to provide a constructor or any arguments at all.
For example PHP offers ReflectionClass::newInstanceWithoutConstructor
Cheers

Why do you need an InstanceMirror and why can't you use a ClassMirror?
Just list all the available constructors from the ClassMirror and then use a constructor with 0 arguments to create a new instance.
The PHP Version says: "Creates a new class instance without invoking the constructor.". For me this totally makes no sense. That's why there are constructors: To be called at creation time.

New
If the class doesn't have a constructor, a default constructor with no arguments is implicitly created for this class and you can use it.
If a class has one or more explicit constructors, you can create a new instance only by using one of them.
Old
I'm not sure if I fully understand your questions, but basically - no. If your class doesn't have a constructor an implicit default constructor is used.
An instance of a class is created with new SomeClass which creates a new instance and calls the constructor. There are other ways like literals {'x': 1, 'y': 2} but I'm pretty sure this way a constructor is called as well.

Related

Why factory constructor can't be used in invoking superclass?

Minimal reproducible code:
class Foo {
Foo();
factory Foo.named() => Foo();
}
class Bar extends Foo {
Bar() : super.named(); // Error
}
As there's no async-await thing in the factory constructor, and it instantly invokes the concrete constructor, so why isn't it allowed to use factory constructor like that?
Before null safety, null could be returned from a factory constructor but it is no longer a case. So, I think a factory constructor should now be allowed.
factory function can return subclass, which means can call subclass's init function.
if subclass self can call super.factory function, then it become cycling.
Calling a generative constructor creates a new object, then runs the constructor and super-class constructors to initialize that new object.
They are initializers which initialize the object created by the (now often implicit) new operator.
The super-constructor chained by the (non-redirecting) generative constructor is called to initialize the same object, and ensure that its fields are fully initialized, before ever giving anyone access to that object.
Calling a factory constructor does not create any new object, it just executed the body of that constructor which can do anything that normal code can. (That may or may not include calling a generative constructor to create an object. It can also just throw and never create any object.) A factory constructor cannot access this, because there is no "current object" before it returns one.
Let's assume that Foo has an int foo = 42; field. A factory constructor like the Foo.named here creates a new object by calling Foo() - the generative constructor.
When you do new Bar(), you create a new Bar object and ask the super-constructors to initialize that object. The named factory constructor has no access to that new object that would be created by calling new Bar(), it cannot access this and it cannot help initialize the foo field of that object. It creates a new, unrelated, Foo object and now you have 1) a partially initialized Bar object and 2) a Foo object, neither of which can be the result of calling a Bar constructor.
Your generative constructors must call a super-class generative constructor, which does the same until reaching the Object constructor. That's the only way to ensure that the newly generated object is fully initialized.
One of the main purposes of a factory constructor is to allow returning an existing instance. That's basically incompatible with a derived class constructor that must create a new object. (I suppose it doesn't necessarily have to be; you could imagine a design where two derived instances virtually inherit from a shared instance of a base class. However, that would be a lot of extra work for something of little benefit and that could be very confusing.)
Additionally, one of the other main purposes of a factory constructor is precisely to prevent a class from being subclassed by making all non-factory constructors private.

What's mean colon inside a dart class?

I'm trying understand what's the mean of this two final lines of code, on colons... It's a syntax question.
I'm following this github example and I have this doubt on my head.
Can someone help me with this?.
class DietPlan extends ParseObject implements ParseCloneable {
DietPlan() : super(keyDietPlan);
DietPlan.clone() : this();
The part after : is called "initializer list.
It is a list of expressions that can access constructor parameters and can assign to instance fields, even final instance fields.
The first colon, i.e. DietPlan() : super(keyDietPlan); means that you are calling the super constructor, constructor of ParseCloneable in this case.
This is a core OOP concept, you can extend or implement one class to another and you must call the superclass constructor if you do so. This is just a style of doing the same in Dart.
The second colon works in similar way, to understand that you need to understand what is cloning of objects,
Object cloning refers to creation of exact copy of an object. It creates a new instance of the class of current object and initializes all its fields with exactly the contents of the corresponding fields of this object.
This is whats happening on the second line.

dart advantage of a factory constructor identifier

I've been investigating JSON parsing for my Flutter app and have a question about factory constructors that I can't resolve. I'm trying to understand the advantage of using a factory constructor versus a plain constructor. For example, I see quite a few JSON parsing examples that create a model class with a JSON constructor like this:
class Student{
String studentId;
String studentName;
int studentScores;
Student({
this.studentId,
this.studentName,
this.studentScores
});
factory Student.fromJson(Map<String, dynamic> parsedJson){
return Student(
studentId: parsedJson['id'],
studentName : parsedJson['name'],
studentScores : parsedJson ['score']
);
}
}
I've also seen an equal number of examples that DON'T declare the constructor as a factory. Both types of classname.fromJSON constructors create an object from the JSON data so is there an advantage to declaring the constructor as a factory or is using a factory here superfluous?
A normal constructor always returns a new instance of the current class (except when the constructor throws an exception).
A factory constructor is quite similar to a static method with the differences that it
can only return an instance of the current class or one of its subclasses
can be invoked with new but that is now less relevant since new became optional.
has no initializer list (no : super())
So a factory constructor can be used
to create instances of subclasses (for example depending on the passed parameter
to return a cached instance instead of a new one
to prepare calculated values to forward them as parameters to a normal constructor so that final fields can be initialized with them. This is often used to work around limitations of what can be done in an initializer list of a normal constructor (like error handling).
In your example this code
studentId: parsedJson['id'],
studentName : parsedJson['name'],
studentScores : parsedJson ['score']
could be moved to the body of a normal constructor because no final fields need to be initialized.
In the particular example in the question, there's no advantage to using a factory constructor. It makes no difference to callers (there is no expectation to receive an already-existing object), and this particular factory constructor could have been a normal constructor that delegated to the main constructor instead.
In general, the factory keyword is not very useful and provides an advantage only in special circumstances.
A factory constructor vs. a normal constructor
A factory constructor invokes another constructor.
Since a factory constructor does not directly create a new instance, it cannot use a constructor initializer list.
A normal constructor always returns a new instance of the class. A factory constructor is permitted to return an existing instance, an instance of a derived class, or null. (However, some people dislike returning null from a factory constructor. Note that returning null from a factory constructor is disallowed with null-safety.)
Due to the above, an extending class cannot invoke a factory constructor as the superclass constructor. A class that provides only factory constructors therefore cannot be extended with derived classes.
A factory constructor vs. a static method
A factory constructor can be the unnamed, default constructor of a class.
A factory constructor can be used with new. (But using new is now discouraged.)
Until Dart 2.15, constructors could not be used as tear-offs (i.e., they could not be used as callbacks), whereas static methods could.
Static methods can be async. (A factory constructor must return a type of its class, so it cannot return a Future.)
Factory constructors can be declared const.
In null-safe Dart, a factory constructor cannot return a nullable type.
In generated dartdoc documentation, a factory constructor obviously will be listed in the "Constructors" section (which is prominently at the top) whereas a static method will be in the "Static Methods" section (which currently is buried at the bottom).
After I've been noticing and wondering the same, and given I don't think the other answers actually answer the question ("I've been investigating JSON parsing [...] I'm trying to understand the advantage of using a factory constructor verses a plain constructor"), here my try:
there's no advantage or difference that I could see or understand, when parsing json, in using a factory constructor instead of a plain constructor. I tried both, and both works fine, with all the types of parameters. I decided eventually to adopt the factory constructor, because of the convenience of how the code is written, and readability, but it's a matter of choice and both will work fine in all the cases.
One of the uses of factory constructor is, we can decide which instance to create, at run-time and move all the logic to the parent's factory constructor
let's say you have 1 parent class and 2 subclasses
class GolderRetriever extends Dog{
GolderRetriever(String name):super(name);
}
class Labrador extends Dog{
Labrador(String name):super(name);
}
Then we have the parent class
class Dog{
final String name;
Dog(this.name);
factory Dog.createInstance({required String name,DogType type=DogType.UNKNOWN}){
if(type==DogType.GOLDEN_RETRIEVER){
return GolderRetriever(name);
}
else if(type==DogType.DALMATION){
return Labrador(name);
}else{
return Dog(name);
}
}
}
and also I have enum DogType
enum DogType{
GOLDEN_RETRIEVER,DALMATION,UNKNOWN
}
Then in the main Method, you just delegate which subclass instance you want to create to the parent Dog class
main() {
Dog myDog = Dog.createInstance(name:"Rocky",type:DogType.DALMATION);
Dog myNeighboursDog = Dog.createInstance(name:"Tommy",type:DogType.GOLDEN_RETRIEVER);
Dog strayDog = Dog.createInstance(name:"jimmy");
}
you can't do this with a named constructor as you can create only the instance of that class(Dog class), not its subtypes.
Now the responsibility of which instance to create is delegated to the parent class. This can remove a lot of if-else boilerplate code. When you want to change the logic, you just change that in Animal class alone.

Multiple inheritance with Dart and accessing public variables from multiple levels up

I've been working with Dart for a few weeks now, and so far so good. I've run into a problem, however, when trying to access variables from a class that's a few levels higher. I'm not sure how best to explain this without an actual sample, so here's a quick example:
http://pastebin.com/r2ru6G2w
To put this as simply as possible:
AClass has a variable named "parameter."
BClass inherits from AClass, also has a constructor parameter (incomingParameter) that is assigned to the "parameter" variable from AClass.
CClass inherits from BClass, also has a constructor parameter (incomingParameter) that is simply passed on to BClass via the super initializer.
DClass inherits from CClass, but does not have any constructor parameter. Instead, I'm trying to pass the "parameter" variables all the way from AClass into the super initializer.
This results in an error, that says "Only static members can be accessed in initializers." Fair enough. Any idea how to get around this?
Thanks for all the help,
MR

Telling StructureMap to use another Constructor

I have a class with 2 constructors.
MyClass()
and
MyClass(IMyService service)
How do I tell StructureMap then whenever I do a 'new MyClass()' it should actually call the second constructor and not the first constructor.
Please help.
If you call new MyClass(), then StructureMap is not involved at all. No amount of StructureMap configuration will change the behavior.
If you call ObjectFactory.GetInstance<MyClass>(), StructureMap will by default call the constructor with more parameters.
If you want StructureMap to use a different constructor, you can specify the constructor (via PHeiberg's answer):
x.SelectConstructor<IMyClass>(() => new MyClass(null));
Or you can just tell StructureMap explicitly how to create the instance using the overload of Use() that accepts a Func<>:
x.For<IMyClass>().Use(ctx => new MyClass(ctx.GetInstance<IMyService>()))
Joshua's answer is covering all aspects. As a side note in order to configure Structuremap to choose a specific constructor without hardcoding the arguments to the constructor as done in Joshua's example you can use the SelectContructor method:
x.SelectConstructor<MyService>(() => new MyService());
The lambda in the SelectConstructor method call should invoke the needed constructor (put nulls or any value of the correct type for all parameters present). See the documentation for further info.
When using a DI container like structuremap it's best to have just a single constructor on every class. This constructor has to resolve all the dependencies of the class, if IMyService is a dependency (which looks a bit strange though) this should always be resolved when instantiating so the parameterless constructor is not needed.

Resources