C# Class Inheritance - c#

I am working with insurance and have two different policy types - motor and household, represented by two different classes, Motor and Household.
Both have several bits of data in common, so both would inherit from another class called Policy. When a user logs into the app, they could have either a motor or a household policy, so the app needs to display the generic information and the information unique to Motor or Household. To encapsulate all this, i have a response object that has both a Motor member and a Household member, as shown below:
public class Response
{
...
private MotorPolicy _motorPolicy;
private HouseholdPolicy _householdPolicy;
....
}
The code below should demonstrate:
if (response.PolicyType == Enumerations.PolicyType.Motor)
{
lblDescription.Text = response.MotorPolicy.Description;
lblReg.Text = response.MotorPolicy.Reg;
}
else
{
lblDescription.Text = response.HouseholdPolicy.Description;
lblContents.Text = response.HouseholdPolicy.Contents;
}
The MotorPolicy doesn't have Contents property and the HouseholdPolicy doesn't have a Reg property.
But I really want to simply do:
if (response.PolicyType == Enumerations.PolicyType.Motor)
{
lblDescription.Text = response.Policy.Description;
...
}
I have tried using generics, could couldn't find the right solution.

Your response only needs a Policy type, you can then store a MotorPolicy or HouseholdPolicy type into it.
Then your response just needs to check for data type
if (response.Policy is MotorPolicy) ....
Alternatively have an abstract method or a property returning data from an abstract method on the Policy type that is fully inplemented by the child classes and returns reg data or contents data as apporpriate.

Each Policy descendant (now you have two, you might have more in the future, right?) should have their own UI controls which "know" how to deal with the policy information. The same approach can be used for other things, such as a "controller" for policy objects etc.
The response can then be made generic:
public class Response<T> where T: Policy {
...
private T _policy;
....
}
Alternatively, you could have a more generic approach which uses reflection to display the information, but those are usually less "sexy" in their appearance and usability (think of the Property Grid in the VS designer).

public interface IPolicy
{
string Description { get; }
string Reg { get; }
string Contents { get; }
}
public class MotorPolicy : IPolicy
{
public string Description
{
get { return ...; }
}
public string Reg
{
get { return ...; }
}
public string Contents
{
get { return String.Empty; }
}
}
public class HousholdPolicy : IPolicy
{
public string Description
{
get { return ...; }
}
public string Reg
{
get { return String.Empty; }
}
public string Contents
{
get { return ...; }
}
}
public class Response
{
...
private IPolicy _policy;
....
}
Now you don't need an Enumeration to show which type you've implemented, you can just say
lblDescription.Text = response.Policy.Description;
lblReg.Text = response.Policy.Reg;
lblContents.Text = response.Policy.Contents;
Edit: Alternate solution
public interface IPolicy
{
string Description { get; }
}
public interface IHasReg
{
string Reg { get; }
}
public interface IHasContents
{
string Contents { get; }
}
public class MotorPolicy : IPolicy, IHasReg
{
public string Description
{
get { return ...; }
}
public string Reg
{
get { return ...; }
}
}
public class HouseholdPolicy : IPolicy, IHasContents
{
public string Description
{
get { return ...; }
}
public string Contents
{
get { return ...; }
}
}
public class Response
{
...
private IPolicy _policy;
....
}
This leaves you with more code in the calling function
lblDescription.Text = response.Policy.Description;
IHasReg hasReg = response.Policy as IHasReg;
if (hasReg != null) lblReg.Text = hasReg.Reg;
IHasContents hasContents = response.Policy as IHasContents;
if (hasContents != null) lblContents.Text = hasContents.Contents;
but is considerably more extensible than other options presented and complies with your desire to avoid functionality in the implementation which doesn't make sense.

One option is to add a member to Policy that synthesizes all the derived class' relevant properties to provide a summary:
public abstract class Policy {
public string Description { get; set; }
public abstract string Summary { get; }
}
public class MotorPolicy: Policy {
public override string Summary {
get { return this.Description + "\r\n" + this.Reg; }
}
}
public class HouseholdPolicy: Policy {
public override string Summary {
get { return this.Description + "\r\n" + this.Contents; }
}
}
This centralizes the logic and makes the user interface code simple:
label.Description.Text = response.Policy.Summary;
That basic implementation sacrifices the ability to format the subsections separately. You could overcome that by exposing the summary as a collection of strings:
public abstract IEnumerable<string> SummarySections { get; }
If you want to display the derived classes' details in fundamentally different ways, you'll have to embrace the conditional logic in the user interface layer (for example, you might list the household policy's contents in a table, but show a scanned image for the motor policy's registration).

Use the template pattern:
Create a base class called Policy with a virtual abstract get method to determine the description of the policy.
public abstract class Policy
{
protected virtual string GetDescription()
{
return string.Empty()
}
public string Description
{
get
{
return GetDescription();
}
}
}
public MotorPolicy : Policy
{
public override string GetDescription()
{
return ..... ////specific description implementation for MotorPolicy
}
}
public HouseHoldPolicy : Policy
{
public override string GetDescription()
{
return ..... ////specific description implementation for HouseholdPolicy
}
}
public class Response
{
...
private MotorPolicy _motorPolicy;
private HouseholdPolicy _householdPolicy;
private PolicyType _policyType;
....
public Policy Policy
{
get
{
if (_policyType== PolicyType.Motor)
{
return _motorPolicy;
}
if (_policyType== PolicyType.Household)
{
return _householdPolicy;
}
return null;
}
}
}
client code:
if (response.Policy != null)
{
lblDescription.Text = response.Policy.Description;
...
}
Let MotorPolicy and HouseholdPolicy derive from Policy and override the abstract get method from the base and create a specific implementation of it.
In the Response class just get the description.

The simplest solution would be to implement an interface with a description property and a "contents" property, and then in your motor policy class, create a dummy "contents" property which returns "reg".

Can your response contain either a MotorPolicy or a HouseholdPolicy or, can it contain one of each?
If you are dealing with one or the other then create a base type that both classes inherit that defines the common properties. When you output the common properties just cast the Policy as the base type and use that.

My immediate thought is to go for:
public abstract class Response
{
public abstract Policy Policy {get;}//can be used for stuff for dealing with all policies.
public static Response GetResponse(Policy policy)
{//factory method
if(policy is MotorPolicy)
return new MotorResponse((MotorPolicy)policy);
if(policy is HouseholdPolicy)
return new HouseholdResponse((HouseholdPolicy)policy);
throw new ArgumentException("Unexpected policy type");
}
}
public class MotorResponse : Response
{
private readonly MotorPolicy _motorPolicy;
public MotorResponse(MotorPolicy policy)
{
_motorPolicy = policy;
}
protected override Policy Policy
{
get { return _motorPolicy; }
}
// motor specific stuff
}
public class HouseholdResponse : Response
{
private readonly HouseholdPolicy _householdPolicy;
public HouseholdResponse(HouseholdPolicy policy)
{
_householdPolicy = policy;
}
protected override Policy Policy
{
get { return _householdPolicy; }
}
// household specific stuff
}

I would try something like this:
public class Response
{
public Policy SelectedPolicy {get;set;}
//I don't think you need these, but hard to
//say without seeing the rest of the code
...
private MotorPolicy _motorPolicy;
private HouseholdPolicy _householdPolicy;
....
}
then
lblDescription.Text = response.SelectedPolicy.Description;
if (SelectedPolicy is MotorPolicy)
lblReg.Text = ((MotorPolicy)response.SelectedPolicy).Reg;
else if (SelectedPolicy is HouseholdPolicy)
lblContents.Text = ((HouseholdPolicy)response.SelectedPolicy).Contents;
I would not put both Reg and Contents in the base class or interface. If I do what's the purpose of inheritance if all classes look the same? The only benefits I would get would be types, and that's not going to gain me much in this case.

maybe I don't understand the question but I would just use inheritence
define policy as
public class Policy
{
public string Description{ get; set;}
public string Details {get; set;}
}
public class MotorPolicy:Policy
{
public void SetReg(string reg)
{
base.Details = reg;
}
}
public class HousePolicy:Policy
{
public void SetContents(string contents)
{
base.Details = contents;
}
}
and call by
private void Form1_Load(object sender, EventArgs e)
{
MotorPolicy mp = new MotorPolicy();
mp.Description = "Motor";
SetForm(mp);
}
private void SetForm(Policy p)
{
lblDescription.Text = p.Description;
lblDetail.Text = p.Details;
//then if you still need specifics
if (p.GetType() == typeof(MotorPolicy))
{
MotorPolicy mp = p as MotorPolicy;
//continue assigning mp
}
else if (p.GetType() == typeof(HousePolicy))
{
HousePolicy hp = p as HousePolicy;
//continue assigning Hp
}
}
Note I put reg/contents as a field detail as they are both string types. If one was int vs string then they would have to be done separate.

define the Policy interface and implement it in your both the policy classes
Interface IPolicy{
int Reg {get;set;};
string Contents {get;set;};
}
MotorPolicy : Policy,IPolicy {
string IPolicy.Contents
{get;set;};
int IPolicy.Reg
{get;set;};
}
HouseholdPolicy : Policy , IPolicy {
string IPolicy.Contents
{get;set;};
int IPolicy.Reg
{get;set;};
}

Yours is a unique example of "Refactoring condition to Polymorphism" [Fowler].
And then your method should accept the proper object and do as below:
public void Update(IPolicy policy)
{
lblDescription.Text = policy.Description;
lblReg.Text = .Reg;
}

Well, I dislike abstract classes so I went with an interface for Policy
public interface IPolicy
{
string Description { get; set;}
void Display();
}
Then we inherit from it to create MotorPolicy
public class MotorPolicy : IPolicy
{
public string Description { get; set; }
public string Reg { get; set; }
public void Display()
{
Console.WriteLine(string.Format("Description: {0}", Description));
Console.WriteLine(string.Format("Reg: {0}", Reg));
}
}
Then for response I changed the Policy to a List in the off chance that you can have both or either. Now we've offloaded the handling of displaying the data to the specific policy itself.
public class Response
{
public List<IPolicy> Policies { get; set; }
public void Display()
{
Policies.ForEach(p => p.Display());
}
public void Display(Type t)
{
var policy = (from p in Policies
where p.GetType() == t
select p).FirstOrDefault();
policy.Display();
}
}
This could easily be changed to not use the List and we can get rid of the overloaded Display.

Related

Add property to all responses in asp.net core

I have an API with multiple endpoints. I'd like to add a property to all endpoint responses, without adding it to each endpoint response model individually.
Ex:
public class MyClass
{
public string MyProperty { get; set; } = "Hello";
}
public class MyOtherClass
{
public string MyOtherProperty { get; set; } = "World";
}
public class MyController : ControllerBase
{
[HttpPost]
public async Task<ActionResult<MyClass>> EndpointOne(POSTData data)
{
// implementation omitted
}
[HttpPost]
public async Task<ActionResult<MyOtherClass>> EndpointTwo(POSTOtherData otherData)
{
// implementation omitted
}
}
Calling either endpoint returns a JSON representation of MyClass or MyOtherClass as appropriate - i.e.
{ "MyProperty":"Hello" } or { "MyOtherProperty":"World" }
I want to add a property, say a string ApiName, to all endpoints in the API, so that the result of the above code would be either (as appropriate)
{ "MyProperty":"Hello", "ApiName":"My awesome API" }
or
{ "MyOtherProperty":"World", "ApiName":"My awesome API" }
Is there a way to hook into the JSON-stringified result just before returning and add a top-level property like that? If so, I presume I'd have to wire it up in startup.cs, so I've been looking at app.UseEndpoints(...) methods, but haven't found anything that's worked so far. Either it's not added the property, or it's replaced the original result with the new property.
Thanks in advance!
Use Newtonsoft.Json in your net web api
Register a custom contract resolver in Startup.cs:
builder.Services.AddControllers()
.AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = CustomContractResolver.Instance);
The implementation:
public class CustomContractResolver : DefaultContractResolver {
public static CustomContractResolver Instance { get; } = new CustomContractResolver();
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
var properties = base.CreateProperties(type, memberSerialization);
// add new property
...
properties.Add(newProp);
return properties;
}}
See more Json.net Add property to every class containing of a certain type
You can add a base class with the shared property. Should work for both XML and JSON.
public class MyApiClass
{
public string ApiName => "MyAwesomeApi";
}
public class MyClass : MyApiClass
{
public string MyProperty { get; set; } = "Hello";
}
public class MyOtherClass : MyApiClass
{
public string MyOtherProperty { get; set; } = "World";
}
public class MyController : ControllerBase
{
[HttpPost]
public async Task<ActionResult<MyClass>> EndpointOne(POSTData data)
{
// implementation omitted
}
[HttpPost]
public async Task<ActionResult<MyOtherClass>> EndpointTwo(POSTOtherData otherData)
{
// implementation omitted
}
}
My 0.02 cents says to implement an abstract base class.
Abstract class inheritance look similar to a standard inheritance.
public class MyClass:MyAbstractClass
{
[JsonPropertyName("Class Property")]
public string MyProperty { get; set; } = "Hello";
}
public class MyOtherClass:MyAbstractClass
{
[JsonPropertyName("Class Property")]
public string MyOtherProperty { get; set; } = "World";
}
However the abstract class will allow you to implement additional features in the event you need them in the future.
public abstract class MyAbstractClass{
[JsonPropertyName("API Name")]
public string ApiName{get;set;}="My Aweomse API";
//Just a thought if you want to keep track of the end point names
//while keeping your object names the same
[JsonIgnore(Condition = JsonIgnoreCondition.Always)]
public string EndPointName{
get{
return get_endpoint_name();
}}
private string get_endpoint_name(){
return this.GetType().Name;
}
//May as well make it easy to grab the JSON
[JsonIgnore(Condition = JsonIgnoreCondition.Always)]
public string As_JSON{
get {
return to_json();
}}
private string to_json(){
object _myObject = this;
string _out;
JsonSerializerOptions options =
new JsonSerializerOptions {
WriteIndented = true };
_out =
JsonSerializer.Serialize(_myObject, options);
return _out;
}
}
Probably should have implemented a generic return object, then you could just loop through the task results. I suppose you still can if you have the task return only the JSON string.
public static void run(){
Task<MyClass> _t0 = task0();
Task<MyOtherClass> _t1 = task1();
Task[] _tasks = new Task[]{_t0,_t1};
Task.WhenAll(_tasks).Wait();
Console.WriteLine(""
+$"{_t1.Result.ApiName}:\n"
+$"End Point: {_t1.Result.EndPointName}:\n"
+$"JSON:\n{_t1.Result.As_JSON}");
Console.WriteLine(""
+$"{_t0.Result.ApiName}:\n"
+$"End Point: {_t0.Result.EndPointName}:\n"
+$"JSON:\n{_t0.Result.As_JSON}");
}
private static Task<MyClass> task0(){
return Task.Run(()=>{
Console.WriteLine("Task 0 Doing Something");
return new MyClass();
});
}
private static Task<MyOtherClass> task1(){
return Task.Run(()=>{
Console.WriteLine("Task 1 Doing Something");
return new MyOtherClass();
});
}
And of course the aweosome...awesome:-) results:
Another thought is that you could implement your two different tasks as abstract methods, but that's a different conversation all together.
In addition to all of the great answers, I prefer to use Action Filter and ExpandoObject.
In Program File you should add your custom action Filter.
builder.Services.AddControllers(opt =>
{
opt.Filters.Add<ResponseHandler>();
});
and ResponseHandler acts like below:
public class ResponseHandler : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
IDictionary<string, object> expando = new ExpandoObject();
foreach (var propertyInfo in (context.Result as ObjectResult).Value.GetType().GetProperties())
{
var currentValue = propertyInfo.GetValue((context.Result as ObjectResult).Value);
expando.Add(propertyInfo.Name, currentValue);
}
dynamic result = expando as ExpandoObject;
result.ApiName = context.ActionDescriptor.RouteValues["action"].ToString();
context.Result = new ObjectResult(result);
}
public void OnActionExecuting(ActionExecutingContext context)
{
}
}

Using best practice for chain responsibility in ASP.NET Core

I have a scenario for login user. I write this code for check user if validate return success message.
I am using the chain responsibility pattern for this validation but it seems ugly because I need to more new in this class.
Now I want to write clean and best practice for using this pattern.
How can I do this ?
public abstract class ValidateUser
{
protected readonly ValidateUser _validateUser;
public ValidateUser(ValidateUser validateUser)
{
_validateUser = validateUser;
}
public abstract UserContext ValidateUserLogin(UserContext request);
}
CheckIsActive :
public class CheckIsActive : ValidateUser
{
public CheckIsActive(ValidateUser validateUser) : base(validateUser)
{
}
public override UserContext ValidateUserLogin(UserContext request)
{
if (request.Context.IsActive)
{
return _validateUser.ValidateUserLogin(request);
}
return new UserContext
{
Message = "User Not Active"
};
}
}
CheckPhoneConfirmed :
public class CheckPhoneConfirmed : ValidateUser
{
public CheckPhoneConfirmed(ValidateUser validateUser) : base(validateUser)
{
}
public override UserContext ValidateUserLogin(UserContext request)
{
if (request.Context.ConfirmPhoneNumber)
{
return _validateUser.ValidateUserLogin(request);
}
return new UserContext
{
Message="Phone Number Not confirmed"
};
}
}
CheckIsLockedAccount :
public class CheckIsLockedAccount : ValidateUser
{
public CheckIsLockedAccount(ValidateUser validateUser) : base(validateUser)
{
}
public override UserContext ValidateUserLogin(UserContext request)
{
if (!request.Context.IsLockedEnd)
{
return new UserContext
{
Context = request.Context
};
}
return new UserContext
{
Message = $"Your account is deactivated from to date {request.Context.LockedEnd}"
};
}
}
and I use this Validate by this way :
var validate = new CheckIsActive(new CheckPhoneConfirmed(new CheckIsLockedAccount(null)));
var validateUserContext = validate.ValidateUserLogin(new UserContext
{
Context = findUSer.Result,
Message = null
});
You can use .net core Middleware pipeline, which is based upon Chain of Responsibility pattern only.
app.Use(async (context, next) =>
{
if (context.Request.HttpContext.User.HasClaim("IsLockedEnd", "true"))
{
await next();
}
});
app.Use(async (context, next) =>
{
if (context.Request.HttpContext.User.HasClaim("ConfirmPhoneNumber", "true"))
{
await next();
}
});
app.Use(async (context, next) =>
{
if (context.Request.HttpContext.User.HasClaim("IsActive", "true"))
{
await next();
}
});
I dont feel like this pattern fits here for validation.
If you google you find following description of your pattern:
Chain of Responsibility is behavioral design pattern that allows
passing request along the chain of potential handlers until one of
them handles request. The pattern allows multiple objects to handle
the request without coupling sender class to the concrete classes of
the receivers
I dont think any of that is the case in your solution. Since I feel you dont wanna handle different validations at different places?? I think you are missusing this pattern as a decorator pattern.
Instead try the following:
How about you split your objects into following:
First you need a abstract class so you can define later you validation rule
public abstract class ValidationRule
{
public string Property { get; set; }
public string Error { get; set; }
public ValidationRule(string property)
{
Property = property;
Error = property + " is not valid";
}
public ValidationRule(string property, string error)
: this(property)
{
Error = error;
}
// validation method. To be implemented in derived classes
public abstract bool Validate(Validator validator);
// gets value for given business object's property using reflection
protected object GetPropertyValue(Validator validator)
{
// note: reflection is relatively slow
return validator.GetType().GetProperty(Property).GetValue(validator, null);
}
}
Then you can this class to make a more concrete validator. Maybe a finished rule or something you can even reuse more as for example:
public class ValidateRegex : ValidationRule
{
protected string Pattern { get; set; }
public ValidateRegex(string propertyName, string pattern)
: base(propertyName)
{
Pattern = pattern;
}
public ValidateRegex(string propertyName, string errorMessage, string pattern)
: this(propertyName, pattern)
{
Error = errorMessage;
}
public override bool Validate(Validator validator)
{
return Regex.Match(GetPropertyValue(validator).ToString(), Pattern).Success;
}
}
and then make a final rule out of it
public class ValidateEmail : ValidateRegex
{
public ValidateEmail(string propertyName) :
base(propertyName, #"\w+([-+.]\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*")
{
Error = propertyName + " is not a valid email address";
}
public ValidateEmail(string propertyName, string errorMessage) :
this(propertyName)
{
Error = errorMessage;
}
}
The Validator can look something like this:
public abstract class Validator
{
// list of business rules
List<ValidationRule> rules = new List<ValidationRule>();
// list of validation errors (following validation failure)
List<string> errors = new List<string>();
// gets list of validations errors
public List<string> Errors
{
get { return errors; }
}
// adds a business rule to the business object
protected void AddRule(ValidationRule rule)
{
rules.Add(rule);
}
// determines whether business rules are valid or not.
// creates a list of validation errors when appropriate
public bool IsValid()
{
bool valid = true;
errors.Clear();
foreach (var rule in rules)
{
if (!rule.Validate(this))
{
valid = false;
errors.Add(rule.Error);
}
}
return valid;
}
}
You can use now the validator as following (Note if constructor when you implement a lot of different validation rules):
public class Person : Validator
{
public Person ()
{
AddRule(new ValidateEmail("Email"));
AddRule(new ValidateId("MemberId"));
AddRule(new ValidateRequired("Email"));
AddRule(new ValidateLength("Email", 1, 100));
AddRule(new ValidateRequired("CompanyName"));
AddRule(new ValidateLength("CompanyName", 1, 40));
AddRule(new ValidateRequired("City"));
AddRule(new ValidateLength("City", 1, 15));
AddRule(new ValidateRequired("Country"));
AddRule(new ValidateLength("Country", 1, 15));
}
public int MemberId { get; set; }
public string Email { get; set; }
public string CompanyName { get; set; }
public string City { get; set; }
public string Country { get; set; }
public int NumOrders { get; set; }
public DateTime LastOrderDate { get; set; }
}
If you call now the IsValid() method all your validationrules get executed.
I feel like this is kinda what you want. If you dont wanna tie it to an object, you could try to create a standalone validator and composite the validator into the class where you need it instead from deriving from it.

.Net 4.0 Optimized code for refactoring existing "if" conditions and "is" operator

I have following C# code. It works fine; but the GetDestination() method is cluttered with multiple if conditions by using is operator.
In .Net 4.0 (or greater) what is the best way to avoid these “if” conditions?
EDIT: Role is part of the business model, and the destination is purely an artifact of one particular application using that business model.
CODE
public class Role { }
public class Manager : Role { }
public class Accountant : Role { }
public class Attender : Role { }
public class Cleaner : Role { }
public class Security : Role { }
class Program
{
static string GetDestination(Role x)
{
string destination = #"\Home";
if (x is Manager)
{
destination = #"\ManagerHomeA";
}
if (x is Accountant)
{
destination = #"\AccountantHomeC";
}
if (x is Cleaner)
{
destination = #"\Cleaner";
}
return destination;
}
static void Main(string[] args)
{
string destination = GetDestination(new Accountant());
Console.WriteLine(destination);
Console.ReadLine();
}
}
REFERENCES
Dictionary<T,Delegate> with Delegates of different types: Cleaner, non string method names?
Jon Skeet: Making reflection fly and exploring delegates
if-else vs. switch vs. Dictionary of delegates
Dictionary with delegate or switch?
Expression and delegate in c#
Having virtual property which would be overriden in derived classes should do the trick:
class Role
{
public virtual string Destination { get { return "Home"; } }
}
class Manager : Role
{
public override string Destination { get { return "ManagerHome;"; } }
}
class Accountant : Role
{
public override string Destination { get { return "AccountantHome;"; } }
}
class Attender : Role
{
public override string Destination { get { return "AttenderHome;"; } }
}
class Cleaner : Role
{
public override string Destination { get { return "CleanerHome;"; } }
}
class Security : Role { }
I didn't make the property abstract, to provide default Home value when it's not overriden in derived class.
Usage:
string destination = (new Accountant()).Destination;
Console.WriteLine(destination);
Console.ReadLine();
Here's one option:
private static readonly Dictionary<Type, string> DestinationsByType =
new Dictionary<Type, string>
{
{ typeof(Manager), #"\ManagerHome" },
{ typeof(Accountant), #"\AccountantHome" },
// etc
};
private static string GetDestination(Role x)
{
string destination;
return DestinationsByType.TryGetValue(x.GetType(), out destination)
? destination : #"\Home";
}
Note:
This doesn't cope with null parameters. It's not clear whether or not you actually need it to. You can easily add null handling though.
This doesn't copy with inheritance (e.g. class Foo : Manager); you could do that by going up the inheritance hierarchy if necessary
Here's a version which does deal with both of those points, at the cost of complexity:
private static string GetDestination(Role x)
{
Type type = x == null ? null : x.GetType();
while (type != null)
{
string destination;
if (DestinationsByType.TryGetValue(x.GetType(), out destination))
{
return destination;
}
type = type.BaseType;
}
return #"\Home";
}
EDIT: It would be cleaner if Role itself had a Destination property. This could either be virtual, or provided by the Rolebase class.
However, it could be that the destination is really not something the Role should concern itself with - it could be that Role is part of the business model, and the destination is purely an artifact of one particular application using that business model. In that sort of situation, you shouldn't put it into Role, as that breaks separation of concerns.
Basically, we can't tell which solution is going to be most suitable without knowing more context - as is so often the way in matters of design.
Approach 1 (Selected): Using dynamic keyword to implement multimethods / double dispatch
Approach 2: Use a dictionary to avoid if blocks as mentioned in Jon Skeet’s answer below.
Approach 3: Use a HashList with delegates if there is condition other than equality (For example, if input < 25). Refer how to refactor a set of <= , >= if...else statements into a dictionary or something like that
Apporach 4: Virtual Functions as mentioned in MarcinJuraszek’s answer below.
MultiMethods / Double Dispatch approach using dynamic keyword
Rationale: Here the algorithm changes based on the type. That is, if the input is Accountant, the function to be executed is different than for Manager.
public static class DestinationHelper
{
public static string GetDestinationSepcificImplm(Manager x)
{
return #"\ManagerHome";
}
public static string GetDestinationSepcificImplm(Accountant x)
{
return #"\AccountantHome";
}
public static string GetDestinationSepcificImplm(Cleaner x)
{
return #"\CleanerHome";
}
}
class Program
{
static string GetDestination(Role x)
{
#region Other Common Works
//Do logging
//Other Business Activities
#endregion
string destination = String.Empty;
dynamic inputRole = x;
destination = DestinationHelper.GetDestinationSepcificImplm(inputRole);
return destination;
}
static void Main(string[] args)
{
string destination = GetDestination(new Security());
Console.WriteLine(destination);
Console.WriteLine("....");
Console.ReadLine();
}
}
This is a strongly typed, imperative language so if statements and type checking are going to happen.
Having said that, have you considered a virtual method on Role that can be overridden to provide a destination string?
A further alternative, a lookup table!
Dictionary<Type, string> paths = new Dictionary<TYpe, string>()
{
{ typeof(Manager), #"\ManagerHomeA" }
{ typeof(Accountant), #"\AccountantHomeC" }
{ typeof(Cleaner), "Cleaner" }
}
string path = #"\Home";
if(paths.ContainsKey(x.GetType())
path = paths[x];
One way to do it would be to use a map instead of an if:
//(psuedocode)
private Dictionary<Type, string> RoleMap;
void SomeInitializationCodeThatRunsOnce()
{
RoleMap.Add(typeof(Manager), #"\ManagerHome");
RollMap.Add(typeof(Accountant), #"\AccountantHome");
// ect...
}
string GetDestination(Role x)
{
string destination;
if(!RoleMap.TryGet(x.GetType(), out destination))
destination = #"\Home";
return destination;
}
Further reading: http://www.hanselman.com/blog/BackToBasicsMovingBeyondForIfAndSwitch.aspx
Role should have a virtual function that would return destination:
public virtual string GetDestination()
{
return "Home";
}
And all the classes should override this function and return the correct string. Then in the code you would have:
var role = new Accountant();
string destination = role.GetDestination();
I hope that helps. There may be typos, I am writing from head.
you can either use an interface definition or an abstract method / property
with interface:
public interface IDestinationProvider
{
sting Destination { get; }
}
string GetDestination(Role role)
{
var provider = role as IDestinationProvider;
if (provider != null)
return provider.Destination;
return "Default";
}
with an abstract base class
abstract class Role
{
public abstract string GetDestination();
}
class Manager : Role
{
public virtual string GetDestination() { return "ManagerHomeA"; }
}
string GetDestination(Role role)
{
return #"\" + role.GetDestination();
}
or with attributes:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class DestinationAttribute : Attribute
{
public DestinationAttribute() { this.Path = #"\Home"; }
public string Path { get; set; }
}
[Destination(Path = #"\ManagerHome")]
public class Manager : Role { }
string GetDestination(Role role)
{
var destination = role.GetType().GetCustomAttributes(typeof(DestinationAttribute), true).FirstOrDefault();
if (destination != null)
return destination.Path;
return #"\Home";
}

Encapsulating Action<T> and Func<T>?

I'm trying to make a design for some sort of IExecutable interface. I will not get into details, but the point is that I have several Actions that need to be executed from a base class. They may take different parameters (no big deal), and they may/may not return a value.
So far, this is my design:
public abstract class ActionBase
{
// ... snip ...
}
public abstract class ActionWithResultBase<T>: ActionBase
{
public abstract T Execute();
}
public abstract class ActionWithoutResultBase: ActionBase
{
public abstract void Execute();
}
So far, each of my concrete actions need to be a child from either ActionWithResultBase or ActionWithoutResult base, but I really don't like that. If I could move the definition of Execute to ActionBase, considering that the concrete class may or may not return a value, I will have achieved my goal.
Someone told me this could be done with using Func and Action, for which I totally agree, but I can't find a way to have that into one single class so that the caller would know if the action is going to return a value or not.
Brief: I want to do something like:
// Action1.Execute() returns something.
var a = new Action1();
var result = a.Execute();
// Action2.Execute() returns nothing.
var b = new Action2();
b.Execute();
If you want a lightweight solution, then the easiest option would be to write two concrete classes. One will contain a property of type Action and the other a property of type Func<T>:
public class ActionWithResult<T> : ActionBase {
public Func<T> Action { get; set; }
}
public class ActionWithoutResult : ActionBase {
public Action Action { get; set; }
}
Then you can construct the two types like this:
var a1 = new ActionWithResult<int> {
CanExecute = true,
Action = () => {
Console.WriteLine("hello!");
return 10;
}
}
If you don't want to make Action property read/write, then you could pass the action delegate as an argument to the constructor and make the property readonly.
The fact that C# needs two different delegates to represent functions and actions is quite annoying. One workaround that people use is to define a type Unit that represents "no return value" and use it instead of void. Then your type would be just Func<T> and you could use Func<Unit> instead of Action. The Unit type could look like this:
public class Unit {
public static Unit Value { get { return null; } }
}
To create a Func<Unit> value, you'll write:
Func<Unit> f = () => { /* ... */ return Unit.Value; }
The following interfaces should do the trick -- it's essentially copying the Nullable pattern
public interface IActionBase
{
bool HasResult { get; }
void Execute() { }
object Result { get; }
}
public interface IActionBase<T> : IActionBase
{
new T Result { get; }
}
public sealed class ActionWithReturnValue<T> : IActionBase<T>
{
public ActionWithReturnValue(Func<T> action) { _action = action; }
private Func<T> _action;
public bool HasResult { get; private set; }
object IActionBase.Result { get { return this.Result; } }
public T Result { get; private set; }
public void Execute()
{
HasResult = false;
Result = default(T);
try
{
Result = _action();
HasResult = true;
}
catch
{
HasResult = false;
Result = default(T);
}
}
}
public sealed class ActionWithoutReturnValue : IActionBase
{
public bool HasResult { get { return false; } }
object IActionBase.Result { get { return null; } }
public void Execute() { //... }
}
You know that you can ignore the return value of a method right? You don't have to use it.
what about something simple:
public class ActionExecuter
{
private MulticastDelegate del;
public ActionExecuter(MulticastDelegate del)
{
this.del = del;
}
public object Execute(params object[] p)
{
return del.DynamicInvoke(p);
}
}

How to change the class of an object dynamically in C#?

Suppose I have a base class named Visitor, and it has 2 subclass Subscriber and NonSubscriber.
At first a visitor is start off from a NonSubscriber, i.e.
NonSubscriber mary = new NonSubscriber();
Then later on this "mary" subscribed to some services, and I want to change the type of "mary" to Subscriber.
What is the conventional way to do that?
can't do that. sorry. C# is not a dynamic language.
You will have to create a new mary = new Subscriber(); and copy all relevant properties.
But a better approach might be to model it differently: Give Visitor a list of subscriptions. An empty list means a NonSubscriber.
You cant do this type of conversion.
What you should do is treat mary as a visitor, and when time arrives, create a new instance of "subscriber":
Visitor mary = new NonSubscriber();
// Do some Visitor operations
...
// Now mary is a Subscriber
mary = new Subscriber();
You could use the GOF design patterns State or Strategy to model such an behaviour. Using these patterns, it seems during runtime as if the class of the objects has been changed.
It seems that you have some design problems. I think that it would be better to redesign your code like:
class Visitor
{
private bool isSubscriber = false;
public bool IsSubscriber
{
get { return isSubscriber; }
}
public void Subscribe()
{
// do some subscribing stuff
isSubscriber = true;
}
public void Unsubscribe()
{
// do some unsubscribing stuff
isSubscriber = false;
}
}
You cannot change the type of a variable at runtime. You need to create a new instance.
mary = new Subscriber();
Create a Subscriber constructor that takes a NonSubscriber object as a parameter, or create a method on the NonSubscriber object that returns a Subscriber to save you having to writer the mappping code in multiple places.
It seems like you are encoding information incorrectly into your class hierarchy. It would make more sense to use a different pattern than sub classing here. For example, use only one class (visitor, or perhaps you could name it potential subscriber, whatever seems appropriate) and encode information on the services the object is subscribed to, moving the dynamically changing behavior behind a "Strategy" pattern or some such. There's very little detail in your example, but one thing you could do in C# is to make a "subscriber" property which would change the behavior of the object when the state of the property was changed.
Here's a contrived somewhat related example:
class Price
{
private int priceInCents;
private bool displayCents;
private Func<string> displayFunction;
public Price(int dollars, int cents)
{
priceInCents = dollars*100 + cents;
DisplayCents = true;
}
public bool DisplayCents
{
get { return displayCents; }
set
{
displayCents = value;
if (displayCents)
{
this.displayFunction = () => String.Format("{0}.{1}", priceInCents / 100, priceInCents % 100);
}
else
{
this.displayFunction = () => (priceInCents / 100).ToString();
}
}
}
public string ToString()
{
return this.displayFunction();
}
}
public class User
{
public Subscription Subscription { get; set; }
public void HandleSubscription()
{
Subscription.Method();
}
}
public abstract class SubscriptionType
{
public abstract void Method();
}
public class NoSubscription : SubscriptionType
{
public override void Method()
{
// Do stuff for non subscribers
}
}
public class ServiceSubscription : SubscriptionType
{
public override void Method()
{
// Do stuff for service subscribers
}
}
public class Service2Subscription : SubscriptionType
{
public override void Method()
{
// Do stuff for service2 subscribers
}
}
Think the code explains my answer :)
Adding to the other answers and your comment, you indeed can use the state pattern for your purpose, it would go something like this:
public class MyProgram
{
public void Run()
{
Visitor v = new Visitor("Mary");
Debug.Assert(v.SubscriptionLinkText == "Join now");
v.IsSubscribed = true;
Debug.Assert(v.SubscriptionLinkText == "Today's special");
v.IsSubscribed = false;
Debug.Assert(v.SubscriptionLinkText == "Join now");
}
}
public class Visitor
{
public string Name { get; set; }
private bool _isSubscribed;
public bool IsSubscribed
{
get { return this._isSubscribed; }
set
{
if (value != this._isSubscribed)
{
this._isSubscribed = value;
this.OnSubscriptionChanged();
}
}
}
private SubscriptionBase _subscription;
public string SubscriptionLinkText
{
get { return this._subscription.LinkText; }
}
public Visitor(string name)
{
this.Name = name;
this._isSubscribed = false;
this.OnSubscriptionChanged();
}
private void OnSubscriptionChanged()
{
// Consider also defining an event and raising it here
this._subscription =
SubscriptionBase.GetSubscription(this.IsSubscribed);
}
}
abstract public class SubscriptionBase
{
// Factory method to get instance
static public SubscriptionBase GetSubscription(bool isSubscribed)
{
return isSubscribed ?
new Subscription() as SubscriptionBase
: new NoSubscription() as SubscriptionBase;
}
abstract public string LinkText { get; }
}
public class Subscription : SubscriptionBase
{
public override string LinkText
{
get { return "Today's Special"; }
}
}
public class NoSubscription : SubscriptionBase
{
public override string LinkText
{
get { return "Join now"; }
}
}

Categories

Resources