Passing Interfaces into Dictionary key's - c#-4.0

I have been following following coreclr for a little while and I am new to programming. My question is why do they pass interfaces into Dictionary's especially the key value?
//
// Allocate a new Dictionary containing a copy of the old values, plus the new value. We have to do this manually to
// minimize allocations of IEnumerators, etc.
//
Dictionary newValues = new Dictionary(current.m_localValues.Count + (hadPreviousValue ? 0 : 1));
My understanding is that interface is to implemented by a class. Once implemented it can call/use functions or store data in the classes properties/ variables. I am missing some understanding of interfaces and their use cases but I do not know what that it.
Why do you instantiate a variable to an interface or pass an interface into a parameter? My understanding is you will then have an instance of that variable which still can't hold values nor change state through methods.

Let me explain.
Interface is contract. It just contains method without implementation. Now it may possible that that interface is being implemented by any number of class.
public interface IEntity { int Id {get;set;} }
public class Student : IEntity { public int Id {get;set;} // Interface Property }
public class Teacher : IEntity { public int Id {get;set;} // Interface Property }
Dictionary<IEntity,object> obj = new Dictionary<IEntity,object>(); Student s = new Student(); Teacher t = new Teacher(); obj.Add(s,any object); obj.Add(t,any object);
This is because of interface that your dictionary can hold reference of both type ( Student and Teacher).
In .NET when any object is created it is uniquely identify by GetHashCode() method. // You can find more detail on this on MSDN.
Also Dictionary not means that keys must be only primitive type. This is the reason it is good if you have more than one key ( Like composite key in Database) so it allow you to identify uniquely based on your custom implementation.
Now second Generic.
public class PersonInfo<T> where T : IEntity
{
public string Name {get;set;}
public T Entity {get;set;}
}
PersonInfo<Student> student = new PersonInfo<Student>();
student.T = new Student();
student.Name = "";
PersonInfo<Teacher> Teacher = new PersonInfo<Teacher>();
teacher.T= new Teacher();
teacher.Name = "";

When you have interface. It not actually interface. You always have a reference to object with that interface. And that object is the one responsible for comparison in dictionary
The benefit is not difference from using class as a key. Dictionary can be used as list to iterate KeyValuePair to take key to do some operation. But using interface means you can store various type of class with same interface instead of just one type. Which is decoupled and more flexible

Related

initializing derived class member variables using base class reference object

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);
}

Abstract Azure TableServiceEntity

I want to abstract the implementation of my Azure TableServiceEntities so that I have one entity, that will take an object, of any type, use the properties of that object as the properties in the TableServiceEntity.
so my base object would be like
public class SomeObject
{
[EntityAttribute(PartitionKey=true)]
public string OneProperty {get; set:}
[EntityAttribute(RowKey=true)]
public string TwoProperty {get; set;}
public string SomeOtherProperty {get;set;}
}
public class SomeEntity<T> : TableServiceEntity
{
public SomeEntity(T obj)
{
foreach (var propertyInfo in properties)
{
object[] attributes = propertyInfo.GetCustomAttributes(typeof (DataObjectAttributes), false);
foreach (var attribute in attributes)
{
DataObjectAttributes doa = (DataObjectAttributes) attribute;
if (doa.PartitionKey)
PartitionKey = propertyInfo.Name;
}
}
}
}
Then I could access the entity in the context like this
var objects =
(from entity in context.CreateQuery<SomeEntity>("SomeEntities") select entity);
var entityList = objects.ToList();
foreach (var obj in entityList)
{
var someObject = new SomeObject();
SomeObject.OneProperty = obj.OneProperty;
SomeObject.TwoProperty = obj.TwoProperty;
}
This doesn't seem like it should be that difficult, but I have a feeling I have been looking at too many possible solutions and have just managed to confuse myself.
Thanks for any pointers.
Take a look at Lokad Cloud O/C mapper I think the source code imitates what you're attempting, but has insightful rationale about its different approach to Azure table storage.
http://lokadcloud.codeplex.com/
I have written an alternate Azure table storage client in F#, Lucifure Stash, which supports many abstractions including persisting a dictionary object. Lucifure Stash also supports large data columns > 64K, arrays & lists, enumerations, out of the box serialization, user defined morphing, public and private properties and fields and more.
It is available free for personal use at http://www.lucifure.com or via NuGet.com.
What you are attempting to achieve, a single generic class for any entity, can be implemented in Lucifure Stash by using the [StashPool] attribute on a dictionary type.
I have written a blog post about the table storage context, entities by specifying the entity type. Maybe it can help you http://wblo.gs/a2G
It seems you still want to use concrete types. Thus, the SomeEntity is a bit redundant. Actually, TableServiceEntity is already an abstract class. You can derive SomeObject from TableServiceEntity. From my experience, this won’t introduce any issues to your scenario.
In addition, even with your custom SomeEntity, it is failed to remove the dependence on the concrete SomeObject class in your last piece of code anyway.
Best Regards,
Ming Xu.

Aggregate root and instances creation of child entities

I have an aggregate that includes the entities A, AbstractElement, X, Y and Z. The root entity is A that also has a list of AbstractElement. Entities X,Y and Z inherit from AbstractElement. I need the possibility to add instances of X, Y and Z to an instance of A. One approach is to use one method for each type, i.e. addX, addY and addZ. These methods would take as arguments the values required to create instances of X, Y and Z. But, each time I add a new type that inherits from AbstractElement, I need to modify the entity A, so I think it's not the best solution.
Another approach is to use an abstract add method addAbstractElement for adding AbstractElement instances. But, in this case, the method would take as argument an instance of AbstractElement. Because this method would be called by entities located outside of the aggregate, following DDD rules/recommandations, are these external entities authorized to create instances of AbstractElement? I read in the Eric Evans book that external entities are not authorized to hold references of entities of an aggregate other than the root?
What is the best practice for this kind of problem?
Thanks
From Evan's book, page 139:
"if you needed to add elements inside a preexisting AGGREGATE, you might create a FACTORY METHOD on the root of the AGGREGATE"
Meaning, you should create a factory method on the root (A) which will get the AbstractElement's details. This method will create the AbstractElement (X/Y/Z) according to some decision parameter and will add it to its internal collection of AbstractElements. In the end this method return the id of the new element.
Best Regards,
Itzik Saban
A few comments. As the previous answerer said, it's a good practice to use a factory method. If you can avoid it, never create objects out of the blue. Usually, it's a pretty big smell and a missed chance to make more sense out of your domain.
I wrote a small example to illustrate this. Video is in this case the aggregate root. Inside the boundaries of the aggregate are the video object and its associated comments. Comments can be anonymous or can have been written by a known user (to simplify the example, I represented the user by a username but obviously, in a real application, you would have something like a UserId).
Here is the code:
public class Video {
private List<Comment> comments;
void addComment(final Comment.Builder builder) {
this.comments.add(builder.forVideo(this).build());
// ...
}
}
abstract public class Comment {
private String username;
private Video video;
public static public class Builder {
public Builder anonymous() {
this.username = null;
return this;
}
public Builder fromUser(final String username) {
this.username = username;
return this;
}
public Builder withMessage(final String message) {
this.message = message;
return this;
}
public Builder forVideo(final Video video) {
this.video = video;
return this;
}
public Comment build() {
if (username == null) {
return new AnonymousComment(message);
} else {
return new UserComment(username, message);
}
}
}
}
public class AnonymousComment extends Comment {
// ...
}
static public class UserComment extends Comment {
// ...
}
One thing to ponder on also is that aggregate boundaries contain objects and not classes. As such, it's highly possible that certain classes (mostly value objects but it can be the case of entities also) be represented in many aggregates.

'Unexpected element: XX' during deserialization MongoDB C#

I'm trying to persist an object into a MongoDB, using the following bit of code:
public class myClass
{
public string Heading { get; set; }
public string Body { get; set; }
}
static void Main(string[] args)
{
var mongo = MongoServer.Create();
var db = mongo.GetDatabase("myDb");
var col = db.GetCollection<BsonDocument>("myCollection");
var myinstance = new myClass();
col.Insert(myinstance);
var query = Query.And(Query.EQ("_id", new ObjectId("4df06c23f0e7e51f087611f7)));
var res = col.Find(query);
foreach (var doc in res)
{
var obj = BsonSerializer.Deserialize<myClass>(doc);
}
}
However I get the following exception 'Unexpected element: _id' when trying to Deserialize the document.
So do I need to Deserialize in another way?? What is the preferred way of doing this?
TIA
Søren
You are searching for a given document using an ObjectId but when you save an instance of MyClass you aren't providing an Id property so the driver will create one for you (you can make any property the id by adding the [BsonId] attribute to it), when you retrieve that document you don't have an Id so you get the deserialization error.
You can add the BsonIgnorExtraElements attribute to the class as Chris said, but you should really add an Id property of type ObjectId to your class, you obviously need the Id (as you are using it in your query). As the _id property is reserved for the primary key, you are only ever going to retrieve a single document so you would be better off writing your query like this:
col.FindOneById(new ObjectId("4df06c23f0e7e51f087611f7"));
The fact that you are deserializing to an instance of MyClass once you retrieve the document lends itself to strongly typing the collection, so where you create an instance of the collection you can do this
var col = db.GetCollection<MyClass>("myCollection");
so that when you retrieve the document using the FindOneById method the driver will take care of the deserialization for you putting it all together (provided you add the Id property to the class) you could write
var col = db.GetCollection<MyClass>("myCollection");
MyClass myClass = col.FindOneById(new ObjectId("4df06c23f0e7e51f087611f7"));
One final thing to note, as the _id property is created for you on save by the driver, if you were to leave it off your MyClass instance, every time you saved that document you would get a new Id and hence a new document, so if you saved it n times you would have n documents, which probably isn't what you want.
A slight variation of Projapati's answer. First Mongo will deserialize the id value happily to a property named Id which is more chsarp-ish. But you don't necessarily need to do this if you are just retrieving data.
You can add [BsonIgnoreExtraElements] to your class and it should work. This will allow you to return a subset of the data, great for queries and view-models.
Try adding _id to your class.
This usually happens when your class doesn't have members for all fields in your document.
public class myClass
{
public ObjectId _id { get; set; }
public string Heading { get; set; }
public string Body { get; set; }
}

Automapper and immutability

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

Resources