Inheritance question - declaring abstract and concrete versions of the same property - c#

Okay, two alternatives, but before I begin, you need to know this:
public abstract class GatewayBase { ... }
public class Gateway : GatewayBase { ... }
Alternative #1
public abstract class ModelBase
{
public GatewayBase GatewayBase { get; private set; } // property named GatewayBase
public ModelBase(GatewayBase gateway)
{
GatewayBase = gateway;
}
}
public class Model : ModelBase
{
public Gateway Gateway { get; private set; } // property named Gateway
public Model(Gateway gateway)
: base(gateway)
{
Gateway = gateway;
}
}
Alternative #2
public abstract class ModelBase
{
public GatewayBase Gateway { get; private set; } // property named Gateway
public ModelBase(GatewayBase gateway)
{
Gateway = gateway;
}
}
public class Model : ModelBase
{
public new Gateway Gateway { get; private set; } // property named Gateway plus "new" modifier
public Model(Gateway gateway)
: base(gateway)
{
Gateway = gateway;
}
}
Discussion:
With Alternative #1, the concrete class Model can "see" two versions of Gateway. One is called GatewayBase and the other is called just Gateway, but they both contain the exact same instance. With Alternative #2, technically, there are still two versions of Gateway but one hides the other, so there is effectively only one (unless you bypass it using base.Gateway). I like that Alternative #2 lets me call the property Gateway wherever I am, because it gets used a lot in both the base and concrete classes and it's a short but clear name. Still, I have some hesitation about using the new modifier in this way. Is this really a legitimate scenario for hiding a property?
Which would you choose and why?
Or feel free to suggest other alternatives.
Thanks.
EDIT:
I should mention that GatewayBase and ModelBase are in a dependent assembly, so they don't know anything about Gateway and Model. However, Gateway and Model of course know about GatewayBase and ModelBase.

Option 2 looks cleaner, but don't make a separate backing property, wrap the existing base class' property by casting it up from GatewayBase to Gateway. This way you won't have ambiguities about the Gateway used: it's always the same, just from a different perspective:
public abstract class ModelBase
{
public ModelBase(GatewayBase gateway)
{
this.Gateway = gateway;
}
public GatewayBase Gateway { get; private set; }
}
public class Model : ModelBase
{
public Model(Gateway gateway)
: base(gateway)
{
}
public new Gateway { get { return (Gateway) base.Gateway; } }
}
You can also use generics to keep things a little more flexible for different types of gateways (a bit like IEnumerable<T>). The problem with generics is that you can't cast one C<X> to another C<Y> (well, you can, sometimes, in 4.0). The cleanest way to solve that, is to introduce a non-generic interface, which you implement explicitly on your generic class. This way, it's hidden from view when you're talking to generic instances, but you can still mix your C<X>'s and C<Y>'s.
public interface IModel
{
GatewayBase Gateway { get; }
}
public abstract class ModelBase<TGateway> : IModel
where T : GatewayBase
{
public ModelBase(TGateway gateway)
{
this.Gateway = gateway;
}
public TGateway Gateway { get; private set; }
GatewayBase IModel.Gateway { get { return this.Gateway; } }
}
public class Model : ModelBase<Gateway>
{
public Model(Gateway gateway)
: base(gateway)
{
}
}

I am not sure why you want the second Gateway property. Does Gateway have a different interface than GatewayBase? If so, I see the difference, but generally I think it might not be the best design. I would seriously consider whether Gateway should expose any other properties/methods than GatewayBase. If not, then you don't need the Model.Gateway property.
It is a good idea to only use inheritance when there is an "Is A" relationship between the two classes. That would imply that Gateway "Is A" GatewayBase and should generally have the same properties/methods, at least that are public.

Related

Parametrized Abstract Factory / Factory Method / other creation patterns

I want to have some factory (doesn't matter if Abstract Factory pattern or Factory Method - looks like the second is specific form of the first one. In my case only one object should be created). The thing is that although created products are similar, they depends on some arguments.
How to prepare this architecture in compliance with design patterns?
Current approach below
public abstract class Product {}
public class MyProduct : Product
{
public bool Abc { get; set; }
}
public class YourProduct : Product {}
public abstract class ProductFactory
{
//in some cases parameter not in use
public abstract Product Create(HelpData additionalData);
}
public class MyProductFactory : ProductFactory
{
public override Product Create(HelpData additionalData)
{
return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
}
}
public class YourProductFactory : ProductFactory
{
//unused parameter
public override Product Create(HelpData additionalData)
{
return new YourProduct();
}
}
public class HelpData
{
public bool SomethingImportantForMyProduct { get; set; }
}
EDIT
I see it's not clear so will repeat.
Usually I'm not using patterns just because of using them. But this problem seems not to be border case. Looks rather quite frequent. Going further I believe there's design pattern suitable to this, but I'm not sure which one. For now looks like abstract factory is not right choice.
Don't use design-patterns because you're using design-patterns. Always have in mind when to use one and when not. In your circumstances at least the abstract factory-pattern is wrong, as it assumes all factories to work with the same parameters. So if you have different parameters you surely need different factories.
However there's no way for the abstract factory to guess how to get an instance of a HelpData in some case but not in the other, so either pass it to every abstract factory or completely omit this further abstraction and stay with two independent factories:
public abstract class Product {}
public class MyProduct : Product
{
public bool Abc { get; set; }
}
public class YourProduct : Product {}
public class MyProductFactory
{
public Product Create(HelpData additionalData)
{
return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
}
}
public class YourProductFactory
{
//unused parameter
public Product Create()
{
return new YourProduct();
}
}
public class HelpData
{
public bool SomethingImportantForMyProduct { get; set; }
}
Exposing a parameter only used within one factory to all factories isn't a good idea.
Besides this just imagine you don't have factories but any other classes that have a Create-method, where one needs a parameter, but the other one does not. Why should those two classes derive from the same base-class (in your case the abstract factory), when the don't have any common members? There's apparently no reason for this, so don't overcomplicate things just for the sake of using a pattern which doesn't fit.
Depending on where and how you retrieve additional data you could inject that data to the factory which will use it to construct the object:
public abstract class ProductFactory
{
public abstract Product Create();
}
public class MyProductFactory : ProductFactory
{
private HelpData additionalData;
public MyProductFactory(HelpData additionalData)
{
this.additionalData = additionalData;
}
public override Product Create()
{
return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
}
}
public class YourProductFactory : ProductFactory
{
public override Product Create()
{
return new YourProduct();
}
}
Instead of passing HelpData to constructor of a factory you could inject a service that knows how to retrieve HelpData specific to the object being created. You could pass some other parameter to Create method if it is used for both factories.
I have also googled a bit and found good answer that explains why not https://stackoverflow.com/a/6241219/2138959. Passing a dictionary or a type that has property of dictionary type is also and option but in such approaches client has too much knowledge of a type it want to be created to use abstract factory.

Is There a Name for this Pattern

I've used this pattern many times in a variety of places, usually alongside a plugin pattern.
Some example ways I've used it are for messaging systems, such as creating subscribers to various types of unrelated messages. I've also used it for generic integration workflows that each need a differently shaped context object.
Basically the pattern consists of defining a blank marker interface for a message or context. Then defining a high level workflow interface that works with the message/context interface. You can then use a factory to get a concrete instance of the workflow, and if needed, the workflow can also be responsible for parsing its message / context from a common data format.
Next, you create an abstract generic base workflow whose responsibilty is just to map calls to the interface methods, which pass around the useless marker interface, into calls to abstract methods that take the concrete version of the message/context.
Hopefully that makes sense. I'll provide a code example below. I'd love to know if this pattern has a name because I've noticed that I've used it about 4-5 times now. Also, I'm just fleshing out how to explain the pattern, so if anything about my explanation doesn't make sense please let me know that as well.
The main point is that you can have multiple classes with different method signatures that can still be called via a common interface:
End Result
public class ConcreteA : Base<MessageA>
{
public void Process(MessageA message){...}
public MessageA Parse(IDictionary data){...}
}
public class ConcreteB : Base<MessageB>
{
public void Process(MessageB message){...}
public MessageB Parse(IDictionary data){...}
}
//And both can by called by...
public void Main(){
var data = GetDataFromIntegrationSource(someContext);
IWorkflow impl = Factory.GetConcrete(someContext);
//So in your classes you're able to work with strongly typed parameters,
//But in the consuming code you still can use a common interface
//Consuming code never even knows what the strong type is.
IMessage msg = impl.Parse(data);
impl.Process(msg);
}
FULL EXAMPLE
High Level Interfaces
public interface IGenericeMarkerInterface
{
}
public interface IGenericWorkflow
{
void Process(IGenericeMarkerInterface messageOrContext);
IGenericeMarkerInterface Parse(IDictionary<string, string> commonDataFormat);
}
Abstract Base for Mapping to Concrete Methods
public abstract class GenericWorkflowBase<T> : IGenericWorkflow where T : IGenericeMarkerInterface
{
public void Process(IGenericeMarkerInterface messageOrContext)
{
Process((T)messageOrContext);
}
public IGenericeMarkerInterface Parse(IDictionary<string, string> commonDataFormat)
{
return DoParse(commonDataFormat);
}
public abstract void Process(T messageOrContext);
public abstract T DoParse(IDictionary<string, string> commonDataFormat);
}
Mapping Attributes
public class MappingAttributeUsedByFactoryAttribute : Attribute
{
public WorkflowType SomePropertyForMapping { get; set; }
}
Concrete Implementations
public class SomeRandomlyShapedMessageOrContext : IGenericeMarkerInterface
{
public int ID { get; set; }
public string Data { get; set; }
}
[MappingAttributeUsedByFactory(WorkflowType.IntegrationPartnerB)]
public class ConcreteWorkflow : GenericWorkflowBase<SomeRandomlyShapedMessageOrContext>
{
public override void Process(SomeRandomlyShapedMessageOrContext messageOrContext)
{
//TODO: process the strongly typed message
}
public override SomeRandomlyShapedMessageOrContext DoParse(IDictionary<string, string> commonDataFormat)
{
//TODO: parse the common data into the strongly typed message
}
}
Factory
public static class WorkflowFactory
{
public static IGenericWorkflow Get(WorkflowType workflow)
{
//TODO: find the concrete workflow by inspecting attributes
}
}
Example Usage
public static class Program
{
public static void Main(string[] args)
{
//this could be driven by a UI or some contextual data
var someSortOfWorkflowIdentifier = (WorkflowType)args[0];
var data = GetSomeDictionaryOfData();
var workflow = WorkflowFactory.Get(someSortOfWorkflowIdentifier);
workflow.Process(workflow.Parse(data));
}
}
Yes, it's exactly same as you named it: Marker interface

Can C# constraints be used without a base type?

I have some classes with common properties, however, I cannot make them derive from a base type (LINQ-to-SQL limitations).
I would like to treat them as if they had a base type, but not by using Reflection (performance is critical).
For example:
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
}
public class Vehicle
{
public int Id { get; set; }
public string Label { get; set; }
}
In this case I would be happy if I had the Id property available, regardless of the type I'm holding.
Is there any way in C# to to something similar to this:
public static int GetId<T>(T entity) where T // has an int property 'Id'
{
return entity.Id;
}
I guess I could have used dynamic, however, I'm looking for a way to restrict the code in compile time from using this method for an object that has no Id property.
You can use interfaces:
public interface IHasId
{
int Id { get; }
}
public class User : IHasId { ... }
public class Vehicle : IHasId { ... }
public static int GetId<T>(T entity) where T : IHasId
{
return entity.Id;
}
However, if you are not able to modify the classes to add the interface, you won't be able to do this. No compile-time checks will verify that a property exists on T. You'd have to use reflection - which is slow and obviously not ideal.
There is no way to guarantee a type has a given member without constraining to a common base type or interface. One way to work around this limitation is to use a lambda to access the value
public static int Use<T>(T value, Func<T, int> getIdFunc) {
int id = getIdFunc(value);
...
}
Use(new User(), u => u.Id);
Use(new Vehicle(), v => v.Id);
You can create an interface with the common properties and make your classes implement it:
public interface IEntity
{
int Id { get; set; }
}
public class User : IEntity
{
public int Id { get; set; }
public string FirstName { get; set; }
}
public class Vehicle : IEntity
{
public int Id { get; set; }
public string Label { get; set; }
}
public static int GetId<T>(T entity) where T : IEntity
{
return entity.Id;
}
You could simplify GetId like this:
public static int GetId(IEntity entity)
{
return entity.Id;
}
The other answers mentioning the interface approach are certainly good, but I want to tailor the response to your situation involving Linq-to-SQL.
But first, to address the question title as asked
Can C# constraints be used without a base type?
Generally, the answer is no. Specifically, you can use struct, class, or new() as constraints, and those are not technically base types, and they do give some guidance on how the type can be used. That doesn't quite rise to the level of what you wish to do, which is to limit a method to types that have a certain property. For that, you will need to constrain to a specific interface or base class.
For your specific use case, you mention Linq-to-SQL. If you are working from models that are generated for you, then you should have options to modify those classes without modifying the generated model class files directly.
You probably have something like
// code generated by tool
// Customer.cs
public partial class Customer // : EntityBaseClasses, interfaces, etc
{
public int ID
{
get { /* implementation */ }
set { /* implementation */ }
}
}
And other similar files for things such as Accounts or Orders or things of that nature. If you are writing code that wishes to take advantage of the commonly available ID property, you can take utilize the partial in the partial class to define a second class file to introduce a common interface type to these models.
public interface IIdentifiableEntity
{
int ID { get; }
}
And the beauty here is that using it is easy, because the implementation already exists in your generated models. You just have to declare it, and you can declare it in another file.
public partial class Customer : IIdentifiableEntity { }
public partial class Account : IIdentifiableEntity { }
// etc.
This approach has proven valuable for me when using a repository pattern, and wishing to define a general GetById method without having to repeat the same boilerplate in repository after repository. I can constrain the method/class to the interface, and get GetById for "free."
Either you need to make both classes implement an interface with the properties you need, and use that in the generic constraint, or you write separate methods for each type. That's the only way you'll get compile-time safety.

Calling method defined in Base Interface

If I have the following Interface structure;
public interface IPaymentTypeBase
{
void PayNow();
double Amount { get; set; }
}
public interface IPaymentTypePayPal : IPaymentTypeBase
{
string UserName { get; set; }
string Password { get; set; }
}
public interface IPaymentMethod<T>
{
}
Then I have the following classes;
public class PaymentTypePayPal : IPaymentTypePayPal
{
public string UserName { get; set; }
public string Password { get; set; }
public void PayNow()
{
throw new NotImplementedException();
}
}
public class PaymentMethod<T> : IPaymentMethod<T> where T : IPaymentTypeBase
{
}
Then in my web application I have this;
IPaymentMethod<IPaymentTypePayPal> payer = (IPaymentMethod<IPaymentTypePayPal>) new PaymentMethod<PaymentTypePayPal>();
I'd now like to call payer.PayNow(); but I'm just getting lost in interfaces etc and can't seem to make this work.
I believe this is a simple thing but am just missing the point entierly.
Can anyone help?
Edit
The intention here is to have a set of interface such as PayPal, Voucher, CreditCard all of which do their own payment gateway type of stuff.
So I'd like to instantiate a class that takes the Payment Type as an interface and call that interfaces PayNow method.
payer is of type IPaymentMethod<IPaymentTypePayPal>.
But IPaymentMethod<T> is defined as
public interface IPaymentMethod<T>
{
}
Therefore, it has no methods and you can't call PayNow() on it.
The same is true for PaymentMethod<T>, so you can't call any method on an instance of PaymentMethod<PaymentTypePaypal> either.
Maybe you can explain a little more what your intention is.
I am not quite sure of why you are using that PaymentMethod class... But why cant you modify the interface IPaymentMethod to something like :
public interface IPaymentMethod<T> : IPaymentTypeBase
so that U can call the patNow method??
Personally, I'd use classes rather than interfaces whenever inheritance is involved. Also, in this case you've got more indirection than you probably need. If you model Payment as an abstract base class (with PayNow() and Amount) and PayPalPayment as the subclass, just instantiate the proper subclass from a factory and you're set, with all the flexibility you'd have with your approach, yet easier to understand and maintain, I think. (not really knowing all of the other requirements of your application)

How to use a class as the base, but hide the class type publically?

I am currently just exposing the properties through a generic interface e.g.
public interface IBaseClass
{
int ID { get; set; }
}
internal class MyBaseClass : IBaseClass
{
public MyBaseClass() { }
public int ID { get; set; }
}
public class MyExposedClass : IBaseClass
{
private MyBaseClass _base = new MyBaseClass();
public int ID
{
get { return _base.ID; }
set { _base.ID = value; }
}
}
Then in my main application I can do:
IBaseClass c = new MyExposedClass();
c.ID = 12345;
But can't do:
MyBaseClass b = new MyBaseClass();
This is my desired behaviour.
However, I was just wondering if this is the correct approach? Or if there was a better way?
If you only want to prevent instantiation you could make MyBaseClass abstract (make it's constructor protected as well - it is a good design) and have MyExposedClass derive from it. If you want to completely hide the type your approach seems fine.
This look fine to me. Making small interfaces makes it easier to write decoupled code.
I don't know if this will help, but you can make your base class protected internal. This would mean that any internal class has access to it as if it were public, or any class (from within and without the assembly) can subclass the base class. It won't prevent people from implementing their own sub class though.
Alternatively, exposing through an Interface would be the best way I'd think.
For this you can opt for explicit implementation like this:
public interface IBaseClass
{
int ID { get; set; }
}
internal class MyBaseClass : IBaseClass
{
public MyBaseClass() { }
public int IBaseClass.ID { get; set; }
}
public class MyExposedClass : IBaseClass
{
private MyBaseClass _base = new MyBaseClass();
public int IBaseClass.ID
{
get { return _base.ID; }
set { _base.ID = value; }
}
}
You can refer to a similar post C# Interfaces. Implicit implementation versus Explicit implementation
Make your base class abstract.
You could expose the interface as public, implement an internal sealed implementation of that class, and use a factory approach to build instances of the desired interface. That way the client will never know when you change your implementation, or if you have multiple implementations of the same base interface plugged in the factory. You could also eliminate the set accessors in the interface and put them in the internal implementation to only expose the properties to the outside world. That way the exterior code has to make less assumptions over your implementation and you are better isolated. Please correct me if I'm having a poor/bad image of this approach.
Edit: The factory would be public and you'd need some sort of "transfer object" to pass data to the factory. That transfer object implementation would be public, together with it's interface.
Your example seems to include a poor example of taking advantage of inheritence. Since you included a single property it and couldnt come up with a better example i am guessing that its real. I would suggest in this case forget the base class and stick the property on the derived.

Categories

Resources