Consider the following class:
class MyContext : DbContext
{
public DbSet<Order> Orders { get; set; }
}
and instantiating a new object:
var mycontext = new MyContext();
Why mycontext.Orders is not null? When it was initialized? Who has initialized it? I'm really confused because the base class (DbConetxt) cannot access the derived class properties so it is not possible that the automatic property was initialized in the base object.
From looking at the reflected code, when the DbContext (the base class) is constructed it makes a call to the DbSetDiscoveryService (an internal clasS) - which essentially uses reflection to find all properties on the DbContext, and then initializes those that need initializing.
So in short - using reflection in the constructor.
Related
The Hazelcast documentation on their Portable serialization mechanism says that you are not forced to use a no-arg constructor.
https://hazelcast.org/mastering-hazelcast/#serialization-start
But their example code shows fields being set directly.
#Override
public void readPortable(PortableReader reader) throws IOException {
System.out.println("Deserialize");
this.name = reader.readUTF("name");
}
and the factory used to create instances of the class being deserialized is using a no-arg constructor.
#Override
public Portable create(int classId) {
switch (classId) {
case PERSON_CLASS_ID:
return new Person();
}
return null;
}
Am I right in assuming that you are not forced to use a no-arg constructor but you can't use it to set field values when deserializing? How would you handle enforcing invariants such as never-null fields and how would you deserialize a subclass without making the fields in the superclass protected?
While deserializing you can't maintain invariants since the object is being reconstructed; so some fields are just not set. There is no point resisting this.
And you are not forced to have a no-arg constructor. As long as the factory can create an instance, HZ doesn't care how you create it.
I came across a lot of code in our company codebase with the following structure
class Base
{
public Base (var a, var b)
{
base_a = a;
base_b = b;
}
var base_a;
var base_b;
}
class Derived:Base
{
publc Derived (var a,b,c,d): base (a,d)
{
der_c = c;
der_d = d;
}
var der_c;
var der_d;
var der_e;
}
class Ref
{
Base _ref;
public Ref( var a,b,c,d)
{
_ref = new Derived (a,b,c,d)
}
public void method( )
{
_ref.der_e = 444; // won't compile
}
}
What is the correct way to initialize der_e ? What is the advantages of having a reference of base class and using an object derived class for _ref ? Just the fact that using a base class reference can hold multiple derived class objects ? If that's the case, should all the member variables of derived class be initialized during construction itself (like this: _ref = new Derived (a,b,c,d) ). What if I want to initialize _ref.der_e later in a method ? I know I can do this (var cast_ref = _ref as Derived; cast_ref.der_e = 444) but this look doesn't seem to the best practice. What is the idea of having such a structure and what is the correct of initializing a member of a derived class object after it has been constructed ?
Those are too many questions in a single post.
What is the correct way to initialize der_e ?
For initializing der_e you will have to have Reference of Derived class as it knows about the der_e property and not Base class.
What is the advantages of having a reference of base class and using
an object derived class for _ref ?
Yes that's called Polymorphism which is the essence of Object Oriented Programming. It allows us to hold various concrete implementations without knowing about the actual implementation.
If that's the case, should all the member variables of derived class
be initialized during construction itself (like this: _ref = new
Derived (a,b,c,d) )
There is no such rule. It depends on your scenario. If the values are not meant to be changed after the creation of the object and the values are known before hand during construction of the object then they should be initialized during construction.
Again if there are various scenarios like sometimes values are known and sometimes not then there can be Overloaded Constructors, which take different arguments.
What if I want to initialize _ref.der_e later in a method ?
That is perfectly fine, it depends on what you are trying to achieve. The question is not a concrete one but an abstract one in which it is difficult to comment on what you are trying to achieve.
I know I can do this (var cast_ref = _ref as Derived; cast_ref.der_e =
444) but this look doesn't seem to the best practice.
I am sharing some Java code which is similar to C# as I am from Java background
//This class knows about Base and nothing about the Derived class
class UserOfBase{
Base ref;
//Constructor of UserOfBase gets passed an instance of Base
public UserOfBase(Base bInstance){
this.ref = bInstance;
}
//Now this class should not cast it into Derived class as that would not be a polymorphic behavior. In that case you have got your design wrong.
public void someMethod(){
Derived derivedRef = (Derived)ref; //This should not happen here
}
}
I am sharing some references which would help you with this, as I think the answer can be very long to explain.
Factory Pattern
Dependency Injection
Head First Design Patterns
Posts on SO regarding polymorphism
You can create a constructor in your derived class and map the objects or create an extension method like this:
public static class Extensions
{
public static void FillPropertiesFromBaseClass<T1, T2>(this T2 drivedClass, T1 baseClass) where T2 : T1
{
//Get the list of properties available in base class
System.Reflection.PropertyInfo[] properties = typeof(T1).GetProperties();
properties.ToList().ForEach(property =>
{
//Check whether that property is present in derived class
System.Reflection.PropertyInfo isPresent = drivedClass.GetType().GetProperty(property.Name);
if (isPresent != null && property.CanWrite)
{
//If present get the value and map it
object value = baseClass.GetType().GetProperty(property.Name).GetValue(baseClass, null);
drivedClass.GetType().GetProperty(property.Name).SetValue(drivedClass, value, null);
}
});
}
}
for example when you have to class like this:
public class Fruit {
public float Sugar { get; set; }
public int Size { get; set; }
}
public class Apple : Fruit {
public int NumberOfWorms { get; set; }
}
you can initialize derived class by this code:
//constructor
public Apple(Fruit fruit)
{
this.FillPropertiesFromBaseClass(fruit);
}
I wanted to implement the factory pattern with CDI. Here we have the business case example:
A client provides a string representing a type. Depending on this type the factory returns an implementation of an interface.
I know that there are a lot of questions flying around concerning factory pattern and CDI. The difference I have here is that I resolve the implementation returned by the factory based on a runtime parameter.
I was thinking of using a producer method but then I can not think of how to inject the resolved implementation into the bean where the implementation is needed since this is a runtime parameter which is not necessarily known at contruction time.
So I thought of the pretty straight forward way of using the Instance class.
Here is the basic implementation :
// the interface. Instances of this class are returned from the factory
public interface Product {
}
// one implementation may be returned by the factory
#ProductType("default")
public class DefaultProduct implements Product {
}
// another implementation may be returned by the factory
#ProductType("myProduct")
public class MyProduct implements Product {
}
// the qualifier annotation
#Qualifier
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.FIELD, ElementType.TYPE})
public #interface ProductType {
String value();
}
// the Annotation implementation to select
// the correct implementation in the factory
public class ProductTypeLiteral extends AnnotationLiteral<ProductType>
implements ProductType {
private String type;
public ProductTypeLiteral(String type) {
this.type = type;
}
#Override
public String value() {
return type;
}
}
// the factory itself. It is annotated with #Singleton because the
// factory is only needed once
#Singleton
public class Factory {
#Inject
#Any
private Instance<Product> products;
public Product getProduct(String type) {
ProductTypeLiteral literal = new ProductTypeLiteral(type);
Instance<Product> typeProducts = products.select(literal);
return typeProducts.get();
}
}
In my opinion using Instance is very sophisticated.
But this has one major drawback:
Everytime you cal the Instance.get() method you retrieve a new Instance of Product. This may be fine but the Instance instance keeps a reference of the returned instance internally. So as long as the Factory lives and each time the Instance.get() is called the more instances of Product will exist in the memory and never get garbage collected because a reference is still hold in Instance.
I thought of not making the Factory a singleton but that just shifts the problem and does not solve it. And of course it is against the factory pattern.
Another solution I tried was to iterate through the Instance instead of selecting an implementation with the help of the annotation:
#Singleton
public class Factory {
#Inject
#Any
private Instance<Product> products;
public Product getProduct(String type) {
Product product = null;
for(Product eachProduct : products) {
ProductType productType = eachProduct.getClass().
getAnnotation(ProductType.class)
if(productType.value().equals(type) {
product = eachProduct;
break;
}
}
return product;
}
}
Basically this is working. Now each time depending on the given type I retrieve the same instance of Product. That way the memory is not consumed.
But I don't like it to iterate over a collection when I have the possibility to resolve the correct implementations more elegantly.
Do you have any ideas which may solve the problem? Otherwise I may have to keep the iteration solution.
Herein lies your problem. Instance keeps reference to instances you obtain from it using get() because it is responsible for reclaiming them when they go out of scope (i.e. when the injected Instance goes out of scope. But because you made your factory a singleton, it will never go out of scope. So, make your factory a short-lived scope, like #RequestScoped or even #Dependent, that way all the returned instances will be reclaimed properly.
Maybe it can help you:
Create qualifiers:
#Qualifier
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
public #interface MyProduct{
}
#Qualifier
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
public #interface DefaultProduct{
}
In Factory class:
#Singleton
public class Factory {
public Product getProduct(#MyProduct MyProduct product, #DefaultProduct DefaultProduct defaultProduct) {
//What you wanna do
}
}
I have a base base and derived classes like
[ClaimsPrincipalPermission(SecurityAction.Demand, Resource = "Base",
Operation = "Create")]
public abstract class Base
{
}
[ClaimsPrincipalPermission(SecurityAction.Demand, Resource = "Derived",
Operation = "Create")]
public class Derived : Base
{
}
It never comes to authorization manager to check for base class if I am creating a derived class object.
public class AuthorisationManager : ClaimsAuthorizationManager
{
public override bool CheckAccess(AuthorizationContext context)
{
var resource = context.Resource.First().Value;
var action = context.Action.First().Value;
return context.Principal.HasClaim(resource, action);
}
}
Any idea how can I implement that it should come to check for derived and base class both? Actually I want that if any one of them has permission, object should be allowed to create.
Is that your real scenario? Or do you want to use that in the context of some app framework like ASP.NET?
But IIRC this is the behavior of CAS permissions - you could try the same with good old PrincipalPermission to see if the behavior wrt derivation is the same.
Is it possible to use AutoMapper with Immutable types?
For example my Domain type is immutable and I want to map my view type to this.
I believe it is not but just want this confirmed.
Also as it is best practice to have your domain types immutable, what is the best practice when mapping your view types to domain types?
I typically do the mapping from view types to domain types by hand, as I'll typically be working through a more complex interface, using methods and so on. If you use AutoMapper to go from view to domain, you're now locked in to an anemic domain model, whether you've intentionally decided to or not.
Suppose that you really did want an immutable property on your Domain type, say Id. Your domain type might look something like this:
public class DomainType
{
public DomainType(int id)
{
Id = id;
}
public int Id { get; }
// other mutable properties
// ...
}
Then you can use ConstructUsing using a public constructor of your choice, such as:
CreateMap<ViewType, DomainType>()
.ConstructUsing(vt => new DomainType(vt.Id));
Then map all the mutable properties in the normal way
AutoMapper relies on property setters to do its work, so if you have read-only properties, AutoMapper won't be of much use.
You could override the mapping behaviour and, for example, configure it to invoke a specific constructor, but that basically defeats the purpose of AutoMapper because then you are doing the mapping manually, and you've only succeeded in adding a clumsy extra step in the process.
It doesn't make a lot of sense to me that your domain model is immutable. How do you update it? Is the entire application read-only? And if so, why would you ever need to map to your domain model as opposed to from? An immutable domain model sounds... pretty useless.
P.S. I'm assuming that you mean this AutoMapper and not the auto-mapping feature in Fluent NHibernate or even some other totally different thing. If that's wrong then you should be more specific and add tags for your platform/language.
We have immutable objects using the builder pattern. Mapping them takes a little more boilerplate code, but it is possible
// ViewModel
public class CarModel : IVehicleModel
{
private CarModel (Builder builder)
{
LicensePlate = builder.LicensePlate;
}
public string LicensePlate { get; }
//
public Builder
{
public string LicensePlate { get; set; }
}
}
// Model
public class CarViewModel : IVehicleViewModel
{
private CarViewModel (Builder builder)
{
LicensePlate = builder.LicensePlate ;
}
public ILicensePlate LicensePlate { get; }
//
public Builder
{
public ILicensePlate LicensePlate { get; set; }
}
}
Our AutoMapper Profiles have three mappings registered:
CreateMap<IVehicleModel, CarViewModel.Builder>();
CreateMap<CarViewModel.Builder, IVehicleViewModel>().ConvertUsing(x => x.Build());
CreateMap<IVehicleModel, IVehicleViewModel>().ConvertUsing<VehicleModelTypeConverter>();
The VehicleModelTypeConverter then defines a two stage conversion:
public IVehicleViewModel Convert(IVehicleModel source, IVehicleViewModel destination,
ResolutionContext context)
{
var builder = context.Mapper.Map<CarViewModel.Builder>(source);
var model = context.Mapper.Map<IVehicleViewModel>(builder);
return model;
}
(An implementation of ITypeListConverter<string, ILicensePlate> carries out that mapping).
Usage in our system is as normal:
var result = _mapper<IVehicleViewModel>(_carModel);
This is using AutoMapper v7.0.1
You can use Automapper with classes or records that have properties init only setters. This is new in C# 9.0.
Automapper can set the properties at object creation because the properties have init only setters, but after Automapper has mapped them, they are locked in (immutable).
https://www.tsunamisolutions.com/blog/c-90-records-and-dtos-a-match-made-in-redmond