I am extending this DataContext entity, which looks sort'a like this:
namespace Entities
{
public class User
{
public Int32 Id { get; set; }
public String Username { get; set; }
}
}
.. Like so:
public class User : Entities.User
{
new public Int32 Id
{
get { return base.Id; }
}
public void Insert()
{
using (var dc = new DataContext())
{
/*
The "this" keyword should match the type that InsertOnSubmit() expects.
And it does. But I get the following error:
System.NullReferenceException: {"Object reference not set to an instance
of an object."}
*/
dc.Users.InsertOnSubmit(this); // Exception occurs here
dc.SubmitChanges();
}
}
}
I am using the custom User class like so:
var u = new User { Username = "Test" };
u.Insert();
What I don't get is this: I have instantiated the class, so why am I getting a NullReferenceException?
Update:
Extending entity class: overriding a property with an enumerator while still being able to use the "this" keyword on the Insert/Update and DeleteOnSubmit methods on a DataContext instance
enum AccessLevels
{
Basic,
Administrator
}
namespace Entities
{
public class User
{
public Int32 Id { get; set; }
public String Username { get; set; }
public Int32 AccessLevel { get; set; }
}
}
How would I extend or alter the above entity class and implement the AcessLevels enumerator, replacing the AccessLevel property?--this without altering the signature of the entity class, so I'm able to use the "this" keyword on Insert/Update and DeleteOnSubmit methods on a DataContexts.
You can't extend LINQ-to-SQL entity types in this way via inheritance - you should instead use a partial class to add extra methods to the existing generated entity. Because LINQ-to-SQL supports inheritance (for discriminated tables, etc), it expects an exact match to a known entity type - not unexpected subclasses.
i.e.
namespace Entities {
partial class User {
/* your extra method(s) here */
}
}
In the above, this is combined with the partial class in the designer.cs to create you type.
The other way to do this (if partial class isn't an option) is via an extension method.
static class EntityExtensions {
public static void SomeMethod(this User user) {...}
}
If there are methods common between types, you can do this by declaring an interface, using extension methods on that interface, and using partial classes to add the interface to the specific types:
namespace Entities {
partial class User : IFunkyInterface {
/* interface implementation, if necessary */
}
}
static class EntityExtensions {
public static void SomeMethod(this IFunkyInterface obj)
{...}
}
or if you need to know the type:
static class EntityExtensions {
public static void SomeMethod<T>(this T obj)
where T : class, IFunkyInterface
{...}
}
Re the enum edit (added as a second answer to keep things simple)...
Firstly - is there a direct 1:1 mapping between the enum and the values? For example, if Basic is 7 and Administrator is 12, then:
enum AccessLevels
{
Basic = 7,
Administrator = 12
}
Then change the type of that property in the dbml (via the designer) from int to your (fully-qualified) enum: Entities.AccessLevel. LINQ-to-SQL supports enums either as direct integer mappings, or as direct string mappings.
If this isn't possible (more complex scenerios), you can isolate the storage (int) and object-oriented (enum) models; rename the property to AccessLevelStorage (or anything else you like), and in a partial class do the mapping:
partial class User {
public AccessLevel AccessLevel {
get {
switch(AccessLevelStorage) {
case 1: return AccessLevelStorage.Foo;
... etc
default: ...throw an exception?
}
}
set {
switch(value) {
case AccessLevel.Foo: AccessLevelStorage = 1; break;
...etc
default: ...throw an exception?
}
}
}
The only caveat here is that LINQ queries will only work against the storage properties - not the custom mapped property. If you do your queries at the level that declares the context, you can change the access of the storage property to internal - but if you do queries outside of this assembly you'll need to leave is public. You might want to add [Browsable(false)] to stop it appearing in UI models, but that is about it.
Related
I am curently working on a small project (C#) where I have data to analyse.
To do so, I pass the data into the constructor of a class.
The class makes a first analysis on the data, and a certain value is determined using the data. Using this value I can say that this data is of Type B, C, D, ... and the analysis would continue in another class corresponding to the data type.
This would be it's class diagram representation :
So the "Data" Class should abstract but not really ? ¯\_(ツ)_/¯
I did some reasearch about the factory design pattern, but I think this is not really what I am trying to achieve. Is there maybe an other design pattern that does what I want to do?
Thank you for helping.
If I understand you correctly, you want the base class to determine which child class to create based on the data passed into the constructor. If so, you can't do it that way - a class cannot change itself to be a different/derived type when being constructed.
I assume that all the data types have some common properties and so you decided to put those common properties in a base class. I also assume you don't want each data type child class to have redundant code setting those common properties in the base class. You accomplish that by having the child class call a method in the base class, passing the data. You can do this in the constructors if you wish. For example:
class BaseData
{
BaseData(Dictionary<string,string> data)
{
this.CommonProp1 = data["CommonProp1"];
this.CommonProp2 = data["CommonProp2"];
}
public string CommonProp1 { get; set; }
public string CommonProp2 { get; set; }
}
class DataTypeA : BaseData
{
DataTypeA(Dictionary<string,string> data)
: base(data) // <-- magic here
{
this.TypeA_Prop1 = data["TypeA_Prop1"];
this.TypeA_Prop2 = data["TypeA_Prop2"];
}
public string TypeA_Prop1 { get; set; }
public string TypeA_Prop2 { get; set; }
}
I believe the factory pattern actually is what you want since you want to create an instance of a class in which the type is determined at run time. This is where you encapsulate the code that determines which type of child class to create. Something like:
class DataFactory
{
public static BaseData BuildDataClass(byte[] serializedData)
{
Dictionary<string,string> data = ParseData(serializedData);
switch (data["DataType"])
{
case "TypeA":
return new DataTypeA(data);
default:
return null;
}
}
private static Dictionary<string,string> ParseData(byte[] serializedData)
{
var data = new Dictionary<string, string>();
// bla bla
return data;
}
}
I am trying to limit the use of types by chaining the aggregate IAggregate, the aggregate event IDomainEvent, and Identity together with generics, I have snipped the below code to give context of the issue of what I have got so far.
I have the following interfaces:
public abstract class Identity<T>
{
protected abstract string GetIdentity();
}
public interface IAggregate<T>
{
Identity<T> Identity { get; }
}
public interface IDomainEvent<TIdentity,TIdentity>
where T : Identity<TIdentity>
{
TIdentity Id { get; }
}
I implement with the below:
public class TestUserId : Identity<TestUser>
{
public TestUserId(string name) { Name = name; }
readonly public string Name;
protected override string GetIdentity() => Name.ToLowerInvariant();
}
public class TestUser : IAggregate<TestUser>
{
public TestUser(TestUserId id)
{
Id = id;
var ev = new TestUserCreated()
}
public TestUserId Id { get; }
public Identity<TestUser> Identity => Id;
}
public class TestUserCreated : IDomainEvent<TestUserId, TestUser>
{
public TestUserCreated() { }
public TestUserId Id => throw new NotImplementedException();
}
Then in the command handler, for this event to be used (and for me to be able to obtain the TestUserId which should be member of the domainEvent object).
public interface IDomainEventHandler<TEvent>
{
void Handle(TEvent domainEvent, bool isReplay);
}
That gives me the code:
public class TesterHandler : IDomainEventHandler<TestUser, TestUserCreated>
{
public void Handle(TestUserCreated domainEvent, bool isReplay)
{
// can access the ID (of type TestUserId)
var testUserId = domainEvent.Id;
}
}
So the above TesterHandler is fine exactly how i would want - however the compiler is failing on class TestUserCreated : IDomainEvent<TestUserId, TestUser> with The type TestUserId' cannot be used as type parameter 'TIdentity' in the generic type or method 'IDomainEvent<TIdentity, Type>'. There is no implicit reference conversion from 'TestUserId' to 'Identity<TestUser>'.
What I want is to couple (without OO inheritance) the event to the aggregate, so that it is tied to a specific aggregate type (i.e. specific events are tied to a specific entity, and the entity ID is part of the event type as a field), I want to try and make it impossible to code event handlers for unrelated aggregates.
I am trying to implement but the compiler complains of boxing and implicit casting errors (depending on what i try/guess), in short I am unsure how to code the above.
Given I was unable to create running code as per comments requested (hence the reason for the post) and general complexity, I decided using generics in this way was a bad idea with rationale below.
I currently have code which calls the handler as follows (and this is working fine) passing in the sourceIdentity external to the domainEvent object:
public interface IDomainEventHandler<TIdentity, TEvent>
where TIdentity : IIdentity
where TEvent : IDomainEvent
{
void Handle(TIdentity sourceIdentity, TEvent domainEvent, bool isReplay);
}
I am passing in the aggregate ID external to the IDomainEvent object (and this is desired to keep the events, from an event sourcing perspective, as simple as possible as simple POCO objects without inheritance or involving any framework).
The reason for the question was I just wanted to explore all options with generics (so the domainEvent object could have an interface that would give an ID field) but it started to get complicated quickly, specifically additional template parameters would be required since we are inferring relationships via templates, rather than OO relationships.
Without OO, the relationship would need to be defined somewhere by adding additional types to templates to tie them together interface IDomainEvent<TIdentity,TAggregate,TEvent> and interface IDomainEventHandler<TIdentity, TAggregate, TEvent>, in this case OO inheritance would be preferred and result in way less code.
All this was done to give an interface to obtain the ID, however as if an ID is really needed it can be incorporated in the event as a normal field (without the need for complex OO relationships or templates).
public interface IDomainEvent
{
DateTime OccurredOn { get; set; }
Guid MessageId { get; set; }
}
public class TestUserCreated : IDomainEvent
{
// id can be accessed by whatever needs it by being
// defined explicity within the domain event POCO
// without needing any base class or framework.
public readonly TestUserId Id;
public readonly string Name;
public TestUserCreated(TestUserId id, string name)
{
Id = id;
Name = name;
}
}
My scenario:
public class EntityBase
{
public int ID { get; set; }
[Required()]
public string Name { get; set; }
//And this is what is getting me
//I want a "Type" enum
}
Then derived classes would have different enums that they would assign to Type.
public class AnimalEntity : EntityBase
{
//Type would have an 'animal type' value: Land, Sea or Air
//Implementation code would do something like:
// myAnimal.Type = AnimalType.Land
}
public class PersonEntity : EntityBase
{
//Type would have a 'person type' value: Doctor, Lawyer or Engineer
//Implementation code would do something like:
// myPerson.Type = PersonType.Lawyer
}
public class MonsterEntity : EntityBase
{
//Type would have a 'monster type' value: Goblinoid, Undead
}
So, the big question is what am I trying to do, right? I am trying to create a base repository class, which will return entities grouped by type. All my entities will have some kind of "type", and I want to create a generic "group by type".
public abstract class RepositoryBase<T> : IRepositoryBase<T> where T : EntityBase
{
//Our common GetAsync, GetByIdAsync, and all our other CRUD
//And then something like this:
public IEnumerable<GroupedData<string, T>> GetGroupedByType(string searchTerm)
{
var entities =
from s in DbSet
where (searchTerm == null || s.Name.ToLower().Contains(searchTerm))
group s by s.Type into g
select new GroupedData<string, T> { Key = g.Key.ToString(), Data = g };
return (entities);
}
}
When T is AnimalEntity, I would get groups Land, Sea and Air with the corresponding entities. For PersonEntity, I would get Doctor, Lawyer, Engineer groups.
If my approach/design is invalid or less than ideal, please let me know.
Enum (please pardon me) are kind of second class citizens so first thing you may think about will not work:
class EntityBase<T> where T : enum {
public T Type { get; set; }
}
Unfortunately it doesn't compile, you may then think to replace enum with a base class:
class EntityBase<T> where T : EntityTypeBase {
public T Type { get; set; }
}
Implementing in EntityTypeBase everything you need to be comfortable with them (== and != operators, IConvertible interface and other boilerplate). It's a lot of code and you'll need also to manage that in EF (otherwise you won't be able to use such property in your queries unless you load everything in memory as objects). You may also force the use of enums (with a run-time check) but this will break SQL code generation in EF.
What's I'd suggest in this case is to use a type EF knows and understand. You may use a string (if you wish so) or an integer (as in this example):
class EntityBase
public virtual int Type { get; set; }
}
In a derived class:
class AnimalEntity : EntityBase {
public override int Type {
get { return base.Type; }
set {
if (!Enum.IsDefined(typeof(AnimalType), value))
throw new ArgumentException();
base.Type = (int)value;
}
}
}
In this way you still can use PersonType.Layer and AnimalType.Land keeping also a little of type safety. Of course you need to keep your enums in-sync to do not have duplicated values (otherwise group by won't work).
As last please also consider to use...another entity. If you have another table EntityType:
ID Name ApplicableTo
0 Laywer Person
1 Programmer Person
2 Land Animal
...
What you have to do in the setter is to check if type is applicable or not and you may have few convenience classes that will group them by type:
public static class PersonType {
public static EntityType Lawyer { get { ... } }
public static EntityType Programmer { get { ... } }
}
IMO this is scale better (easier to add new items and you can delegate, in future, some behavior to EntityType items) and it is safer than hard-coded constants (because integrity is granted by DB engine itself). Of course price to pay is extra overhead for the search in the EntityType table (unless you use some caching mechanism).
Two options I can think of:
First, preferably, use a generic type parameter (T in this sample):
public class EntityBase<T>
{
public T Type {get;set;}
}
Supply that type in the type declaration:
public class AnimalEntity : EntityBase<AnimalEnum>
{ }
Second, if you need more freedom, I usually use a list of string contants:
public class EntityBase
{
public string Type {get;set;}
}
public static class AnimalTypes
{
public const string Dog = "dog";
public const string Cat = "cat";
}
I am building an application where the datamodel is fixed, but people (or just me) can extend it by adding classes that inherit from the base class that gets instantiated from the info in the db and serialized in services.
I have three problem areas with this (case 1 2 and 3 in the sample code below).
Case #1 I could maybe solve with an interface, but that doesn't help me with case 2 or 3.
I think the code sample will speak better than my attempts to explain; any idead on how to approach this so that each new field type doesn't need to get manually added to a bunch of places in the code?
public class ManagerClass
{
public ManagerClass()
{
public ManagerClass()
{
}
//Case #1
public void process(AllFields allFields)
{
foreach (Field field in allFields.Fields)
{
//Currently I need to add all extention types as seperate cases here manually
//...this type of logic appears in several places in the code
if (field.GetType().Name == "ExtendedField")
{
//Have the extended field do something in a way particular to it
}
else
{
//Have the base field do something the "normal" way
}
}
}
//Case #2
//Here is another case where currently I am adding each case in by hand
//fieldType is a string here because I am storing what type of field it is in the DB
public void create(string value, string fieldType)
{
//Currently I need to add all extention types as seperate cases here manually
if (fieldType == "ExtendedField")
{
//Create a ExtendedField
}
else
{
//Create a Field
}
}
}
}
[DataContract]
//Case #3
[KnownType(typeof(ExtendedField))] //Currently I need to add all extention types here manually
public class AllFields
{
private List<Field> fields;
public AllFields(){}
[DataMember]
public List<Field> Fields
{
get { return fields; }
set { fields = value; }
}
}
[DataContract]
public class Field
{
private string fieldValue;
public Field(){}
[DataMember]
public string FieldValue
{
get { return fieldValue; }
set { fieldValue = value; }
}
}
[DataContract]
public class ExtendedField : Field
{
private string someOtherAttribute;
public ExtendedField(){}
[DataMember]
public string SomeOtherAttribute
{
get { return someOtherAttribute; }
set { someOtherAttribute = value; }
}
}
Sounds like you're trying to build an miniature extensibility framework. Consider something like this where the extension logic is handled by a FieldHandler:
public class FieldHandler
{
public virtual Field CreateField(string value, string fieldType){...}
}
// Case 2
Field field = null;
foreach (FieldHandler handler in m_handlers)
{
if (handler.SupportsFieldType(fieldType))
{
field = handler.CreateField (value, fieldType);
continue;
}
}
if (field == null)
{
// Create standard field.
field = ...;
}
For extensible Field reading:
Make Field an abstract class, and make all your common methods abstract as well. Classes derived from Field will specify exactly what those methods do.
You can then pass objects of these derived classes back to methods that accept a Field, and they can call the methods of Field without needing to worry about the real class that is being used. Interface would be even better, but you don't get code reuse for common functionality.
For extensible Field creating:
You will always have to do a switch or something somewhere at the boundaries of your program to determine which class to create. Your goal is to do this in only one place. Your design - determining the factory method to use based on data in the DB - is ideal.
Look into making a class that will have the responsibility to create Field objects based on DB data and just pass it around. If it were abstract, you could subclass it and pass it as a parameter to methods, methods that will get the data they want by calling something like fieldFactory.GetNewField(myParameter);.
For extensible serialization:
Research DataContractResolver.
Tips:
If you find yourself having to switch on the type of Field in more than one place (where the constructors are called), you're doing it wrong. An example of this is your process(field) method. Instead, Field or IField should have an abstract Process method. Consumers will just call Field.Process and not care how it is implemented.
Example:
public abstract class Field
{
public abstract void Process();
}
public class ExtendedField : Field
{
public override void Process() { /*Extended Field Specific Stuff Here*/ }
}
//consumer code
public void DoStuffWithABunchOfFieldsOfUnknownType(IEnumerable<Field> fields)
{
foreach (Field field in fields) { field.Process(); }
}
In my current project I need to be able to have both editable and read-only versions of classes. So that when the classes are displayed in a List or PropertGrid the user is not able to edit objects they should not be allowed to.
To do this I'm following the design pattern shown in the diagram below. I start with a read-only interface (IWidget), and then create an edtiable class which implements this interface (Widget). Next I create a read-only class (ReadOnlyWidget) which simply wraps the mutable class and also implements the read only interface.
I'm following this pattern for a number of different unrelated types. But now I want to add a search function to my program, which can generate results that include any variety of types including both mutable and immutable versions. So now I want to add another set of interfaces (IItem, IMutableItem) that define properties which apply to all types. So IItem defines a set of generic immutable properties, and IMutableItem defines the same properties but editable. In the end a search will return a collection of IItems, which can then later be cast to more specific types if needed.
Yet, I'm not sure if I'm setting up the relationships to IMutable and IItem correctly. Right now I have each of the interfaces (IWidget, IDooHickey) inheriting from IItem, and then the mutable classes (Widget, DooHickey) in addition also implement IMutableItem.
Alternatively, I was also thinking I could then set IMutableItem to inherit from IItem, which would hide its read-only properties with new properties that have both get and set accessors. Then the mutable classes would implement IMutableItem, and the read-only classes would implement IItem.
I'd appreciate any suggestions or criticisms regarding any of this.
Class Diagram
Code
public interface IItem
{
string ItemName { get; }
}
public interface IMutableItem
{
string ItemName { get; set; }
}
public interface IWidget:IItem
{
void Wiggle();
}
public abstract class Widget : IWidget, IMutableItem
{
public string ItemName
{
get;
set;
}
public void Wiggle()
{
//wiggle a little
}
}
public class ReadOnlyWidget : IWidget
{
private Widget _widget;
public ReadOnlyWidget(Widget widget)
{
this._widget = widget;
}
public void Wiggle()
{
_widget.Wiggle();
}
public string ItemName
{
get {return _widget.ItemName; }
}
}
public interface IDoohickey:IItem
{
void DoSomthing();
}
public abstract class Doohickey : IDoohickey, IMutableItem
{
public void DoSomthing()
{
//work it, work it
}
public string ItemName
{
get;
set;
}
}
public class ReadOnlyDoohickey : IDoohickey
{
private Doohickey _doohicky;
public ReadOnlyDoohickey(Doohickey doohicky)
{
this._doohicky = doohicky;
}
public string ItemName
{
get { return _doohicky.ItemName; }
}
public void DoSomthing()
{
this._doohicky.DoSomthing();
}
}
Is it OK to create another object when you need a readonly copy? If so then you can use the technique in the included code. If not, I think a wrapper is probably your best bet when it comes to this.
internal class Test
{
private int _id;
public virtual int ID
{
get
{
return _id;
}
set
{
if (ReadOnly)
{
throw new InvalidOperationException("Cannot set properties on a readonly instance.");
}
}
}
private string _name;
public virtual string Name
{
get
{
return _name;
}
set
{
if (ReadOnly)
{
throw new InvalidOperationException("Cannot set properties on a readonly instance.");
}
}
}
public bool ReadOnly { get; private set; }
public Test(int id = -1, string name = null)
: this(id, name, false)
{ }
private Test(int id, string name, bool readOnly)
{
ID = id;
Name = name;
ReadOnly = readOnly;
}
public Test AsReadOnly()
{
return new Test(ID, Name, true);
}
}
I would suggest that for each main class or interface, there be three defined classes: a "readable" class, a "changeable" class, and an "immutable" class. Only the "changeable" or "immutable" classes should exist as concrete types; they should both derive from an abstract "readable" class. Code which wants to store an object secure in the knowledge that it never changes should store the "immutable" class; code that wants to edit an object should use the "changeable" class. Code which isn't going to write to something but doesn't care if it holds the same value forever can accept objects of the "readable" base type.
The readable version should include public abstract methods AsChangeable(), AsImmutable(), public virtual method AsNewChangeable(), and protected virtual method AsNewImmutable(). The "changeable" classes should define AsChangeable() to return this, and AsImmutable to return AsNewImmutable(). The "immutable" classes should define AsChangeable() to return AsNewChangeable() and AsImmutable() to return this.
The biggest difficulty with all this is that inheritance doesn't work terribly well if one tries to use class types rather than interfaces. For example, if one would like to have an EnhancedCustomer class which inherits from BasicCustomer, then ImmutableEnhancedCustomer should inherit from both ImmutableBasicCustomer and ReadableEnhancedCustomer, but .net doesn't allow such dual inheritance. One could use an interface IImmutableEnhancedCustomer rather than a class, but some people would consider an 'immutable interace' to be a bit of a smell since there's no way a module that defines an interface in such a way that outsiders can use it without also allowing outsiders to define their own implementations.
Abandon hope all ye who enter here!!!
I suspect that in the long run your code is going to be very confusing. Your class diagram suggests that all properties are editable (or not) in a given object. Or are your (I'm)mutable interfaces introducing new properties that are all immutable or not, separate from the "core"/inheriting class?
Either way I think you're going to end up with playing games with property name variations and/or hiding inherited properties
Marker Interfaces Perhaps?
Consider making all properties in your classes mutable. Then implement IMutable (I don't like the name IItem) and IImutable as a marker interfaces. That is, there is literally nothing defined in the interface body. But it allows client code to handle the objects as a IImutable reference, for example.
This implies that either (a) your client code plays nice and respects it's mutability, or (b) all your objects are wrapped by a "controller" class that enforces the given object's mutability.
Could be too late :-), but the cause "The keyword 'new' is required on property because it hides property ..." is a bug in Resharper, no problem with the compiler. See the example below:
public interface IEntityReadOnly
{
int Prop { get; }
}
public interface IEntity : IEntityReadOnly
{
int Prop { set; }
}
public class Entity : IEntity
{
public int Prop { get; set; }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var entity = new Entity();
(entity as IEntity).Prop = 2;
Assert.AreEqual(2, (entity as IEntityReadOnly).Prop);
}
}
Same for the case without interfaces. The only limitation, you can't use auto-properties
public class User
{
public User(string userName)
{
this.userName = userName;
}
protected string userName;
public string UserName { get { return userName; } }
}
public class UserUpdatable : User
{
public UserUpdatable()
: base(null)
{
}
public string UserName { set { userName = value; } }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var user = new UserUpdatable {UserName = "George"};
Assert.AreEqual("George", (user as User).UserName);
}
}