How to auto generate Decorator pattern in C# - c#

I have some interface, and a class implementing this interface, say:
interface IMyInterface
{
void Func1();
void Func2();
}
class Concrete : IMyInterface
{
public virtual void Func1() { //do something }
public virtual void Func2() { //do something }
}
Now, I want to create a class that decorates each of the concrete class methods with some specific logic, to be executed in non production environment, before and after the call.
class Decorator : Concrete
{
public override void Func1() { Pre(); base.Func1; Post(); }
public override void Func2() { Pre(); base.Func2; Post(); }
}
My question is there a simpler way to auto generate such class other than use reflection on the interface and create a text file with cs extension?

Personally I would just explicitly log where needed, but if you are set on using a decorator to do this you could use the RealProxy class.
It could look something like this:
public class DecoratorProxy<T> : RealProxy
{
private T m_instance;
public static T CreateDecorator<T>(T instance)
{
var proxy = new DecoratorProxy<T>(instance);
(T)proxy.GetTransparentProxy();
}
private DecoratorProxy(T instance) : base(typeof(T))
{
m_instance = instance;
}
public override IMessage Invoke(IMessage msg)
{
IMethodCallMessage methodMessage = msg as IMethodCallMessage;
if (methodMessage != null)
{
// log method information
//call method
methodMessage.MethodBase.Invoke(m_instance, methodMessage.Args);
return new ReturnMessage(retval, etc,etc);
}
}
}

Have you tried PostSharp? It can help you automatically "instrument" classes and achieve your logging scenario without actually creating decorators.

What about the Logging Application block?
http://msdn.microsoft.com/en-us/library/ff647183.aspx

I have written a T4 template capable of generating decorator for fairly complex classes based on some simple conventions. The project can be found on GitHub - T4Decorators. Works similar to T4MVC, that is where I got the idea.

Could you use T4 and reflection?
Maybe these other questions could help:
T4 Code generation: Access types in current project
How do you use .Net reflection with T4

We have the same requirement and wrote a Roslyn generator to do this, take a look here: https://github.com/proactima/ProxyGen
You need to modify the code slightly to fit your needs. Basically we wrap the methods of an interface (all from a certain namespace) in a 'ReliableServiceCall' method. It's trivial to modify this to do something else.

Best approach here is to use Decorator Pattern via interfaces. I know this is a very old post, but if you use an IoC injector, like SimpleInjector, you can setup these decorator calls in 1 line of code. Then you can do something like this:
public class Decorator : IMyInterface
{
private readonly IMyInterface _next;
public Decorator (IMyInterface next) { _next = next; }
public override void Func1() { Pre(); _next.Func1; Post(); }
public virtual void Func2() { Pre(); _next.Func2; Post(); }
}

Related

Inheritance in Specflow test steps cause Ambiguous Steps

I've read that using inheritance is not possible when using Specflow, which makes sense most of the time. However, I've run across a situation that seems to require the proper the use of inheritance. Here are my classes:
Base Class:
public class StepBaseClass
{
protected readonly ScenarioContext scenarioContext;
public StepBaseClass(ScenarioContext scenarioContext)
{
this.scenarioContext = scenarioContext;
}
}
First Inherited Class:
[Binding]
public class StudioEnterpriseImportConnectorSteps:StepBaseClass
{
public StudioEnterpriseImportConnectorSteps(ScenarioContext scenarioContext) :base(scenarioContext)
{
}
[Given(#"I have a data record that I want to send to the import service")]
public void GivenIHaveADataRecordThatIWantToSendToTheImportService()
{
scenarioContext.Pending();
}
[When(#"I send the information to an invalid URL")]
public void WhenISendTheInformationToAnInvalidURL()
{
scenarioContext.Pending();
}
[Then(#"an error should be generated")]
public void ThenAnErrorShouldBeGenerated()
{
scenarioContext.Pending();
}
}
2nd inherited class:
[Binding]
public class SitemapSteps:StepBaseClass
{
public SitemapSteps(ScenarioContext scenarioContext):base(scenarioContext)
{
}
[When(#"I visit the URL (.*)")]
public void WhenIVisitTheSitemapURL(string URL)
{
scenarioContext.Add("result", TestUtilities.GetResponseCode(URL));
scenarioContext.Add("response", TestUtilities.GetResponseBody(URL));
}
[Then(#"the response code should be (.*)")]
public void ThenTheResponseCodeShouldBe(string responseCode)
{
HttpStatusCode result = scenarioContext.Get<HttpStatusCode>("result");
Assert.Equal(responseCode, result.ToString());
}
}
As you can see, the only thing that I'm inheriting the the scenarioContext, which is something that I need to do in order to write multi-threaded tests. So instead of repeating this piece of code for each of my classes, I would like to be able to inherit from a base class. What is the proper method of initializing that variable so that I can use it in each of my derived classes?
The proper way depends as always on your individual situaion.
I recommend always to not use base classes and use context injection everywhere. The small number of code that is repeated in the constructor is a small price for a good separation and splitting of your bindings and their implementation.
To get more info about this topic, Gaspar Nagy wrote a nice blog article about the pros and cons of step base classes in SpecFlow:
http://gasparnagy.com/2017/02/specflow-tips-baseclass-or-context-injection/
After initializing my Dependency Injection in the Specflow Test hooks, I would have a class called ApplicationContext with a static resolve method which would return me my ScenarioContext instance like so:
public class ApplicationContext
{
public static T Resolve<T>() where T: class
{
return container.GetInstance<T>();
}
}
Then in my steps class, I would resolve the ScenarioContext like this:
scenarioContext = (ScenarioContext)ApplicationContext.Resolve<IScenarioContext>();

Is it a good practice to cast from an interface to some concrete class when needed?

I'am developing a small system and i developed the classic generic repository. For now, i have the following architecture for my DAL.
public interface IRepositorio<T> where T : class
{
T Get(long id);
long Insert(T obj);
bool Update(T obj);
bool Delete(T obj);
}
public abstract class Repositorio<T> : IRepositorio<T> where T : class
{
public IDbConnection Connection
{
get
{
return new SqlConnection(ConfigurationManager.ConnectionStrings["DBFila"].ConnectionString);
}
}
public T Get(long id)
{
//...
}
public long Insert(T obj)
{
//...
}
public bool Update(T obj)
{
//...
}
public bool Delete(T obj)
{
//...
}
}
My concrete repository looks like this:
public class FilaRepositorio : Repositorio<FilaRepositorio>
{
public FilaRepositorio()
{
}
public void SomeCustomMethod()
{
// Some custom method
}
}
I am also using Simple Injector to follow the IoC and DI patterns, for this reason, when i try to call "SomeCustomMethod()" i dont have access to it (obviously). Look:
public class Processador
{
private IRepositorio<FilaModel> _repoFila;
public Processador(IRepositorio<FilaModel> repoFila)
{
_repoFila = repoFila;
}
public void Processar()
{
_repoFila.SomeCustomMethod(); // <-- wrong
((FilaRepositorio)_repoFila).SomeCustomMethod();// <-- works
}
}
Given this i have some questions:
Is a good or acceptable practice to make that cast (FilaRepositorio)?
If its not a good practice, how to write good code for this case?
There are a few options available. The main problem with making the cast is that it is an implementation concern.
What would happen if the injected object was not a FilaRepositorio?
By making the cast you are tightly coupling the class to an implementation concern that is not guaranteed to be the inject dependency. Thus the constructor is not being entirely truthful about what it needs to perform its function.
This demonstrates the need to practice Explicit Dependencies Principle
The Explicit Dependencies Principle states:
Methods and classes should explicitly require (typically through
method parameters or constructor parameters) any collaborating objects
they need in order to function correctly.
One way to avoid it would be to make a derived interface that explicitly exposes the desired functionality of its dependents.
public interface IFilaRepositorio : IRepositorio<FilaModel> {
void SomeCustomMethod();
}
public class FilaRepositorio : Repositorio<FilaModel>, IFilaRepositorio {
public void SomeCustomMethod() {
//...other code removed for brevity.
}
}
and have the Processador depend on that more targeted abstraction.
Now there is no need for the cast at all and the class explicitly expresses what it needs.
public class Processador {
private readonly IFilaRepositorio _repoFila;
public Processador(IFilaRepositorio repoFila) {
_repoFila = repoFila;
}
public void Processar() {
_repoFila.SomeCustomMethod(); // <-- works
}
}
If you need to access a specific method from any part of your application, then that specific method must be part of your abstraction, or else there is no guarantee that you may use it when changing the concrete class.
I do not believe that your use of casting is a good idea at all, what is usually done in this case is to create a specific interface which defines any other method you could need to use:
public interface IFilaRepositorio : IRepositorio<Fila>
{
void SomeCustomMethod();
}
And than use and declare that specific interface in any part of your code where you believe you need to use it:
public class Processador
{
private IFilaRepositorio _repoFila;
public Processador(IFilaRepositorio repoFila)
{
_repoFila = repoFila;
}
public void Processar()
{
_repoFila.SomeCustomMethod();
}
}

Looking for approach to design two classes and one interface

public interface ISaveData
{
void DeleteFile(); // this is common method
//void ChangeBucket(); I don't need this method in GoogleCloudSaveFile. Should I remove this from here
// void AssignPermission(); // I don't need of this method in AzureSaveData. Should I remove this from here?
}
public class AzureSaveData : ISaveData
{
void ChangeBucket()
{...}
void DeleteFile()
{...}
}
public class GoogleCloudSaveFile() : ISaveData
{
void AssignPermission()
{...}
void DeleteFile()
{...}
}
I want to expose Interface to my presentation layer.
How can I design above three classes (2 classes and 1 interface) to expose all methods to my presentation layer.
All methods means:
Delete()
ChangeBucket()
AssignPermission()
Please ask me if you need more explanation
Presentation layer could be like
void Main()
{
ISaveData saveFiles = new GoogleCloudSaveFile(); // This is just example. I will inject this via Dependency Injection framework
saveFiles.Delete();
}
ChangeBucket() and AssignPermission() are just example methods. I wanted to say, our child classes could have different methods like these two.
One solution is I can define these two methods in interface and can leave method body empty of one method but I don't think it will be good approach
As far as I can think based on the information provided by you without getting into the nitty-gritty of what method would lie in which interface, this is the easiest I can think of:
public interface ISaveData
{
void DeleteFile(); // this is common method
}
public interface IPermission
{
void AssignPermission();
}
public interface IBucketOperation //or something else
{
void ChangeBucket();
}
public class AzureSaveData : ISaveData, IBucketOperation
{
public void ChangeBucket()
{
Console.WriteLine("AzureSaveData ChangeBucket");
}
public void DeleteFile()
{
Console.WriteLine("AzureSaveData DeleteFile");
}
}
public class GoogleCloudSaveFile : ISaveData, IPermission
{
public void AssignPermission()
{
Console.WriteLine("GoogleCloudSaveFile AssignPermission");
}
public void DeleteFile()
{
Console.WriteLine("GoogleCloudSaveFile DeleteFile");
}
}
You can use these as follows:
ISaveData x = new GoogleCloudSaveFile();
x.DeleteFile();
(x as IPermission).AssignPermission();
You can also check if the object you create is of the type before typecasting:
if(x is IPermission)
(x as IPermission).AssignPermission();
I am not sure if you are willing to take the following approach but I think this would be better:
public interface IGoogleCloudSaveFile : ISaveData, IPermission { }
public interface IAzureSaveData : ISaveData, IBucketOperation { }
It would be difficult for you to use a common interface and expect it to have different methods available for different type of objects based on the implementation unless you want to ignore design principals and put everything into one interface. In that case, just put everything in one interface, and while implementing it in the classes, just do a
throw new NotImplementedException();

Call abstract method from abstract class constructor

I would like to ask what are the risks of having something as follows:
abstract public class HtmlTemplateBuilder
{
HtmlSource source;
protected HtmlTemplateBuilder()
{
LoadTemplates();
}
public abstract void LoadTemplates();
}
The risk is if a derived class derives from the derived class:
DerivedClass2 -> #DerivedClass1 -> HtmlTemplateBuilder
This can be solved by sealing #DerviedClass1, but are there any more risks or better practices for implementing this functionality?
Thanks
The situation in which this pattern bit me is as follows: at some later stage you want to add a specialized HtmlTemplateBuilder, which can load different templates based on some criteria unknown to the class itself (maybe you decide you want some cool templates on a specific day of the year). That is:
public class SpecialHtmlTemplateBuilder : HtmlTemplateBuilder
{
private bool someCondition;
public override void LoadTemplates()
{
if (someCondition)
{
LoadTemplatesSet1();
}
else
{
LoadTemplatesSet2();
}
}
}
But how are you going to pass someCondition to the class? The following won't work:
public class SpecialHtmlTemplateBuilder : HtmlTemplateBuilder
{
private bool someCondition;
public SpecialHtmlTemplateBuilder (bool someCondition)
{
this.someCondition = someCondition;
}
// ...
}
because the assignment of this.someCondition will be done after calling the base constructor, i.e., after LoadTemplates() is called. Note that sealing derived classes does not solve this problem.
The way to solve this is as #Rahul Misra described: add an explicit Initialize method and call that after the constructor.
Have a look at this link which explains the perils with simple easy to understand examples
https://blogs.msmvps.com/peterritchie/2012/04/25/virtual-method-call-from-constructor-what-could-go-wrong/
I would remove the call to LoadTemplates from constructor and call Initialise on it when the templates actually need to be loaded and used.
abstract public class HtmlTemplateBuilder
{
HtmlSource source;
object locker = new object();
private bool initialised;
protected HtmlTemplateBuilder()
{
}
protected void Initialise()
{
lock (locker)
{
if(initialised)
{
LoadTemplates();
initialised = true;
}
}
}
public abstract void LoadTemplates();
}

.NET Tools: Extract Interface and Implement Wrapper Class

Is there a tool that can generate extract and generate interfaces for existing classes?
I know Visual Studio will extract an Interface for an existing class. However, I would also like to generate a wrapper class that implements that functionality.
I believe this would help tremendously for unit testing.
Example Existing Class:
public class ThirdPartyClass
{
public void Method1(){}
public void Method2(){}
}
This can be generated by Visual Studio (Extract Interface):
public interface IThirdPartyClass
{
void Method1();
void Method2();
}
I would like to go one step further:
public class ThirdPartyClassWrapper : IThirdPartyClass
{
private tpc = new ThirdPartyClass();
public void Method1()
{
tpc.Method1();
}
public void Method2()
{
tpc.Method2();
}
}
Update:
This would be especially useful for static classes. As Morten points out I can just use a stub, however, I would like to break up my coupling if possible.
Found a way around it for non-sealed classes.
1 - Inherit from the external class
class MyWrapper : ExternalClass
2 - Extract interface for all public methods
class MyWrapper : ExternalClass, IExternalClass
3 - Remove the inheritance from the external class
class MyWrapper : IExternalClass
4 - You will get a hint on the class name about members from the interface not being implemented. Alt + Enter on it and let Resharper automatically implement them
5 - Use this code template to wrap properties
get { return $INNERCOMPONENT$.$NAME$; }
set { $INNERCOMPONENT$.$NAME$ = value; }
6 - Use this code template to wrap methods
return $INNERCOMPONENT$.$NAME$($SIGNATURE$);
I don't know a tool that would do that for you.
You probably know, but Visual Studio goes just half step further - it can provide empty implementation of interface. I would stop there if it is one time task.
Depending on actual goal using some other way may work - i.e. for testing you can use mocking frameworks - usually there is a way to wrap existing class and override some methods as needed.
Another really slick way of doing this is to use Resharper to generate the "Delegating members" for you as described here: https://stackoverflow.com/a/2150827/1703887
Steps:
Create a new class that inherits from the class you want to wrap with a private variable of that class' type:
public class ThirdPartyClassWrapper : ThirdPartyClass
{
private ThirdPartyClass _ThirdPartyClass;
}
Do a Alt-Insert in/on the class to use Resharper to generate "Delegating members". Choose the methods you want to expose and pass through to the private variable.
If you have the free version of the GhostDoc extension installed you can highlight all of the created properties, methods, etc. and do a Ctrl-D to automatically grab all of the documentation from the base class and put it on the new members. (Resharper can do this too but I think you'd have to put "new" on each item which would then allow you to Alt-Enter and choose "Add xml-doc comments" from the Resharper popup menu).
You can then delete the base class and do some additional cleanup in case the method/property signatures expose any other types that you need to wrap.
What you are looking for is a stub, this can be done either by making your own stub implementation of the interface, or by using a mocking framework like Rhinomocks. Wrapping a difficult class in another class for testpurposes does nothing good for you.
Regards
Morten
I strongly suggest you look into a mocking framework like Fakeiteasy.
But to give you exactly what you asked for see below. I suspect ReSharper didn't have this operation when others answered.
add the interface to the class you wish to be the wrapping class
class MyWebElement : IWebElement { }
Find/Click "Delegate implementation of "YourInterfaceHere" to a new field
Select your options
Click finish and enjoy your new class
class MyWebElement : IWebElement
{
private IWebElement _webElementImplementation;
public IWebElement FindElement(By #by)
{
return _webElementImplementation.FindElement(#by);
}
public ReadOnlyCollection<IWebElement> FindElements(By #by)
{
return _webElementImplementation.FindElements(#by);
}
public void Clear()
{
_webElementImplementation.Clear();
}
public void SendKeys(string text)
{
_webElementImplementation.SendKeys(text);
}
public void Submit()
{
_webElementImplementation.Submit();
}
public void Click()
{
_webElementImplementation.Click();
}
public string GetAttribute(string attributeName)
{
return _webElementImplementation.GetAttribute(attributeName);
}
public string GetCssValue(string propertyName)
{
return _webElementImplementation.GetCssValue(propertyName);
}
public string TagName
{
get { return _webElementImplementation.TagName; }
}
public string Text
{
get { return _webElementImplementation.Text; }
}
public bool Enabled
{
get { return _webElementImplementation.Enabled; }
}
public bool Selected
{
get { return _webElementImplementation.Selected; }
}
public Point Location
{
get { return _webElementImplementation.Location; }
}
public Size Size
{
get { return _webElementImplementation.Size; }
}
public bool Displayed
{
get { return _webElementImplementation.Displayed; }
}
}

Categories