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)
{
}
}
Related
I have this model with following attributes. (Simplified)
public class Blog {
private string Code { get; set; }
private string Name { get; set; }
private byte[] Image { get; set; }
}
When I make a request to the OData URL for ex: http://localhost/api/odata/Blog, I want only Code and Name properties to be returned, ignoring the Image. And if I make
a request something like http://localhost/api/odata/Blog?$select=(Code,Name,Image) then I want the Image to be returned. How can I make this work?
Using attributes like [IgnoreDataMember] makes it unavailable for OData query to be accessed, therefore it is not a suitable solution.
First, probably properties of the Blog class are public, not private.
I had a similar scenario and resolve it by implementing a custom serializer:
Serializer provider class:
public class MyODataSerializerProvider : DefaultODataSerializerProvider
{
MyResourceSerializer myResourceSerializer;
public MyODataSerializerProvider(IServiceProvider serviceProvider) : base(serviceProvider)
{
myResourceSerializer = new MyResourceSerializer(this);
}
public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
{
if (edmType.IsEntity())
{
return myResourceSerializer;
}
return base.GetEdmTypeSerializer(edmType);
}
}
Serializer class:
public class MyResourceSerializer : ODataResourceSerializer
{
public MyResourceSerializer(ODataSerializerProvider serializerProvider) : base(serializerProvider) { }
public override ODataResource CreateResource(SelectExpandNode selectExpandNode, ResourceContext resourceContext)
{
var resource = base.CreateResource(selectExpandNode, resourceContext);
if (selectExpandNode.SelectAllDynamicProperties)
{
resource.Properties = resource.Properties.Where(p => p.Name != "Image");
}
return resource;
}
}
And configuration of course:
routeBuilder.MapODataServiceRoute("OData", "odata", b =>
{
b.AddService(Microsoft.OData.ServiceLifetime.Singleton, sp => edmModel);
var conventions = ODataRoutingConventions.CreateDefault();
//Workaround for https://github.com/OData/WebApi/issues/1622
conventions.Insert(0, new AttributeRoutingConvention("OData", app.ApplicationServices, new DefaultODataPathHandler()));
//Custom Convention
b.AddService<IEnumerable<IODataRoutingConvention>>(Microsoft.OData.ServiceLifetime.Singleton, a => conventions);
b.AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(ODataSerializerProvider), sp => new MyODataSerializerProvider(sp));
});
This is my code:
// Controller
[HttpGet("{id}")]
[MyFilter]
public async Task<MyCustomType> Load(string id)
{
return new MyCustomType(....);
}
// Custom attribute
public class MyFilterAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext context)
{
// Can I have my MyCustomType result here?
}
}
I need to implement some special logic in case of specific property values of MyCustomType result.
Public class MyCustomType
{
// assuming that there will be more properties
public int Id { get; set; }
public string Name { get; set; }
}
// Now, Move to Controller method.
public class CustomController : Controller
{
[HttpGet({"id"})]
[MyFilter]
public async Task<MyCustomType> Load(string id)
{
// Do some async operations
// Or do some Db queries
// returning MyCustomType
MyCustomType typeToReturn = new MyCustomType();
typeToReturn.Id = 1;
typeToReturn.Name = "something";
return typeToReturn;
}
}
// Well here goes the attribute
public class MyFilterAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext context)
{
// you have to do more digging i am using dynamic to get the values and result.
dynamic content = context.Result;
if (content != null)
{
dynamic values = content.Value;
}
}
}
EDIT changed the code and ran it in a dot net core project and i was able to get the values, how ever i have used dynamic you can dig more on it.
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);
}
}
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.
Is it possible to do something like the following:
public class ChildClass : BaseClass
{
public ChildClass(BaseClass o)
{
base = o;
}
}
Basically, I want a transparent way to wrap a base class inside of other functionality. One example I've thought of is a custom Settings Provider which transparently audits the settings passed through it.
public class SettingsAuditor : SettingsProvider
{
public SettingsAuditor(SettingsProvider o)
{
base = o;
}
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
{
// Log the property change to a file
base.SetPropertyValues(context, propvals);
}
}
Then I could do the following:
mySettingsProvider = new SettingsAuditor(mySettingsProvider);
And all changes would go through the overridden SetPropertyValues before passing to the original object.
I could use a private SettingsProvider member, but then I either cannot inherit from SettingsProvider, or have an entire SettingsProvider (base) not being used at all.
I'm using C# 4.0 and .Net 4.0.
You cannot do base = o;
What you're looking for is the Decorator Pattern), which is a way to compositionally add functionality at runtime (vs. inheritance).
Instead of trying to set the base, you just contain the inner member. As long as the wrapper implements the same interface or base class as the inner object, you can pass back the new wrapper. You can wrap as many decorators as you want.
Consider:
public interface ICar
{
void Drive();
}
public class Car : ICar
{
public void Drive()
{
Console.WriteLine("vroom");
}
}
public class BuckleUp : ICar
{
ICar car;
public BuckleUp(ICar car) { this.car = car; }
public void Drive()
{
Console.WriteLine("click!");
car.Drive();
}
}
public class CheckMirrors : ICar
{
ICar car;
public CheckMirrors(ICar car) { this.car = car; }
public void Drive()
{
Console.WriteLine("mirrors adjusted");
car.Drive();
}
}
Now consider you have a method that accepts an ICar and tells it to drive. You could give it a Car, and it would work, but you could also wrap that car in a BuckleUp and a CheckMirrors and you wouldn't have to change that method at all. You've modified functionality through composition using the Decorator Pattern.
No. This looks like it should be a Composition vs Inheritance issue. You need to evaluate whether you are a "is a" or a "has a."
A little help for your journey
This is not a complete implmentation and it could probably be done much cleaner with expression trees... but this was a quick swing at faking AOP using DynamicObject with .Net 4.0.
public class MyDynamicWrapper<T> : DynamicObject
{
public T Wrapped { get; private set; }
public Action<T> Pre { get; private set; }
public Action<T> Post { get; private set; }
public MyDynamicWrapper(T wrapped, Action<T> pre, Action<T> post)
{
this.Wrapped = wrapped;
this.Pre = pre;
this.Post = post;
}
public override bool TryGetMember(
GetMemberBinder binder,
out object result)
{
var type = typeof(T);
var method = type.GetMethod(binder.Name);
if (method != null)
{
Func<object> func = () =>
{
if (Pre != null)
Pre(Wrapped);
// support for input parameters could be added here
var ret = method.Invoke(Wrapped, null);
if (Post != null)
Post(Wrapped);
return ret;
};
result = func;
return true;
}
return base.TryGetMember(binder, out result);
}
}
public class MyDynamicWrapper
{
public static MyDynamicWrapper<T> Create<T>(
T toWrap,
Action<T> pre = null,
Action<T> post = null)
{
return new MyDynamicWrapper<T>(toWrap, pre, post);
}
}
public class MyObject
{
public void MyMethod()
{
Console.WriteLine("Do Something");
}
}
class Program
{
static void Main()
{
var myobject = new MyObject();
dynamic mydyn = MyDynamicWrapper.Create(
myobject,
p => Console.WriteLine("before"),
p => Console.WriteLine("after"));
// Note that you have no intellisence...
// but you could use the old implmentation before you
// changed to this wrapped version.
mydyn.MyMethod();
/* output below
before
Do Something
after
*/
}
}
No, but you could fake it:
public class SettingsAuditor
{
SettingsProvider #base;
public SettingsAuditor(SettingsProvider o)
{
#base = o;
}
public void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
{
// Log the property change to a file
#base.SetPropertyValues(context, propvals);
}
}
Note here, #base isn't the actual base, just a varaible named base