I have this object on a class library (project "A" that I want to use in my multiple projects ("B" and "C"):
public class Notification : INotification
{
public string Id { get; set; }
public int Type { get; set; }
public IList<Message> Messages { get; set; }
}
public class Message: IMessage
{
public string Key { get; set; }
public string Value { get; set; }
public string Culture { get; set; }
}
public interface INotification
{
string Id { get; set; }
int Type { get; set; }
IList<Message> Messages { get; set; }
}
Now If I want to create this object on my project "B" I need to do the flowing:
static void Main()
{
Notification notification = new Notification()
{
Id = "someId",
Type = 1,
Messages = new List<Message>()
{
new Message()
{
Culture = "en-US",
Key = "Some key",
Value = "Some value"
}
}
};
Console.WriteLine(notification.Id);
}
The problem is, since all fields are need to be Required
if I don't initialize for example the "Type" no error is shown. What I want is that my project "B" implement the "Notification" object like I want, with all required fields, so my message can not be created without the "Type".
How can I do this? Do I need to create an abstraction?
In c#, the way to require field initialization is to provide them as constructor arguments.
public class Notification : INotification
{
public Notification(string id, int type, IList<Message> messages)
{
this.Id = id;
this.Type = type;
this.Messages = messages;
}
public string Id { get; set; }
public int Type { get; set; }
public IList<Message> Messages { get; set; }
}
Without a default constructor, it is now impossible to construct a Notification without specifying a Type. This is enforced at compile-time, not run-time.
If you want null checks, you will have to add them yourself as part of the constructor logic. You can also add a range check for the int
or other validation.
Note: Type
is a terrible name for a variable.