Auto-generate a Wrapper class in C# using Composition - c#

This should be simple, but I can't find anything out there.
I have a class in one assembly (a shared library -- it's a set of proxy classes for a Web Service)
I have a class in another assembly (web project)
There is a class called "Profile" which is in the Proxy assembly.
There is a set of classes that "use" a Profile in the web project.
When there is no user logged in, a GenericProfile is used.
Following the principle of "separation of concerns"....
The Proxy assembly is used by other projects and is concerned with only the Web Service stuff.
The web project just has web stuff in there
However, now there is this need for a "GenericProfile" -- think of it as "Guest User".
The logical thing to do is to build an interface called IProfile and cause both classes to derive from it. But that would create a circular dependency between the two assemblies.
The next best idea is to create a 3rd assembly called MyInterfaces and put the IProfile in there -- but that causes a violation of the Separation of Concerns principle in my opinion. At the very least, one instance of this problem seems too small a reason to spring for making an extra module in my solution.
Enter the wrapper class -- or the Composite wrapper class (whatever you want to call it)
I'm looking for something that ends up generating something like this below. Is there a tool or Visual Studio extension that will do it? Maybe a .tt file?
namespace WebProject
{
public interface IProfile
{...}
class MyWrapperClass : IProfile
{
Proxy.Profile _profile;
public MyWrapperClass(Proxy.Profile proxy)
{
_profile = proxy;
}
public string IProfile.Property1{ get { return _profile.Property1; } set { _profile.Property1 = value; } }
public string IProfile.Property2{ get { return _profile.Property2; } set { _profile.Property2 = value; } }
public string IProfile.Property3{ get { return _profile.Property3; } set { _profile.Property3 = value; } }
}
}

In Visual Studio 2017
Create your class
namespace WebProject
{
public interface IProfile
{...}
class MyWrapperClass : IProfile
{
private IProfile _wrapped;
}
}
locate your cursor on the IProfile of class MyWrapperClass : IProfile and hit ctrl-. select Implement interface through _wrapped. No need for ReSharper.

I don't completely understand what you are trying to accomplish, but below is how I would generate a wrapper class with ReSharper.
Personally if my employer doesn't want to pay for ReSharper, I buy it. It makes me a better developer. I strongly suggest you consider acquiring it as an investment in your career. Anti-Disclaimer - I am not at all connected with or sponsored by ReSharper.
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; }
}
}

If I was faced with your original problem, I'd put IProfile in your shared library, alongside the Profile class. Your web project can then implement the GenericProfile class that it needs, nothing else needs to know about it, and other clients of the library can do the same as needed. It would also be useful for testing the library.

Related

Wrapper Class Method Parameters

Apologies but this is new to me, I will gladly explain further or edit this post where necessary.
I have a project class library which I need to create a wrapper class library for. This class contains custom classes for constructors, which are then used as parameters in the methods that I'll be calling from my wrapper.
Within my wrapper I don't really want to have to use a using statement referencing the original class library, so I was wondering what the best way to handle these custom constructors are?
Here is an example I knocked up of what the DLL I'm wrapping looks like:
public CustomResult WriteMyDataAndReturnResult(CustomerWriterData data)
{
CustomerResult result = // Do stuff
return result;
}
public partial class CustomResult
{
private int resultId;
private MyResponse response;
public int resultIdField
{
get { return this.resultId; }
set { this.resultId = value; }
}
}
public partial class MyResponse
{
private string myMessage;
public string myMessageField
{
get { return this.myMessage; }
set { this.myMessage = value; }
}
}
public partial class CustomerWriterData
{
private string outputPath;
private string inputPath;
public string myOutputPath
{
get { return this.outputPath; }
set { this.outputPath = value; }
}
public string myInputPath
{
get { return this.inputPath; }
set { this.inputPath = value; }
}
}
So in the example above in my wrapper I'd be looking to have a method that calls WriteMyDataAndReturnResult, but this contains a custom object. What would be the best way to handle things in terms of this? I have toyed with the idea of recreating each of the partial classes in my wrapper, and then having convert methods to change from one to the other, but this seems like I'd be re-writting a lot of code.
Is there a better way for me to avoid having to include a using statement to the original library within code that calls my wrapper project?
Sorted it myself by creating a script that mapped the API to my DTO objects. This wasn't the path I specifically wanted to take, but it at least allowed me to create a separation between the 3rd party API and my main code.

Faking Composition and a Common Interface with Inheritance

We're working with XML and want a common interface amongst the main XML class and all of its components. However, sub-components of the XML class need additional methods, but they also need the main component's methods. Seems like a great use for inheritance.
Here is some code I wrote to accomplish this task. Hopefully, you can get a good idea of what we're going for based on usage:
using System;
namespace SampleNamespace
{
public class SampleClass
{
public static void Main()
{
var xmlDocumentFiles = new XmlDocumentFiles();
xmlDocumentFiles.Files.RootFile.SetFileName("Example.xml");
System.Console.WriteLine(
xmlDocumentFiles.Files.RootFile.GetFileName()
);
}
}
public class XmlDocumentFilesRoot
{
protected string _rootFileName;
public FilesClass Files { get { return (FilesClass) this; } }
}
public class FilesClass : XmlDocumentFilesRoot
{
public RootFileClass RootFile { get { return (RootFileClass) this; } }
}
public class RootFileClass : FilesClass
{
public void SetFileName( string newTitle )
{
_rootFileName = newTitle;
}
public string GetFileName()
{
return _rootFileName;
}
}
public class XmlDocumentFiles : RootFileClass
{
}
}
I was able to cast to child classes and to my surprise it runs just fine. Assuming nothing is put inside of the sub-classes other than methods which wouldn't make sense in the parent, will there ever be any problems (weird compilation errors, runtime crashes) with this class structure?
Are there any alternatives? I had initially tried nested classes + extension methods located outside of the main class, but there was a lot of code needed to set that up. See: https://stackoverflow.com/questions/19415717/using-c-sharp-extension-methods-on-not-in-nested-classes-to-establish-a-common
Extending functionality of a class, sounds like a decorator pattern.
Here's a head-first pdf on this subject:
http://oreilly.com/catalog/hfdesignpat/chapter/ch03.pdf
Also; I would like to discourage the triple '.' :
xmlDocumentFiles.Files.RootFile.SetFileName("Example.xml");
2 is evil, if you need 3: you will definitely lose maintainability.
Hope it helps.

Some design-pattern suggestions needed

C#. I have a base class called FileProcessor:
class FileProcessor {
public Path {get {return m_sPath;}}
public FileProcessor(string path)
{
m_sPath = path;
}
public virtual Process() {}
protected string m_sath;
}
Now I'd like to create to other classes ExcelProcessor & PDFProcessor:
class Excelprocessor: FileProcessor
{
public void ProcessFile()
{
//do different stuff from PDFProcessor
}
}
Same for PDFProcessor, a file is Excel if Path ends with ".xlsx" and pdf if it ends with ".pdf". I could have a ProcessingManager class:
class ProcessingManager
{
public void AddProcessJob(string path)
{
m_list.Add(Path;)
}
public ProcessingManager()
{
m_list = new BlockingQueue();
m_thread = new Thread(ThreadFunc);
m_thread.Start(this);
}
public static void ThreadFunc(var param) //this is a thread func
{
ProcessingManager _this = (ProcessingManager )var;
while(some_condition) {
string fPath= _this.m_list.Dequeue();
if(fPath.EndsWith(".pdf")) {
new PDFProcessor().Process();
}
if(fPath.EndsWith(".xlsx")) {
new ExcelProcessor().Process();
}
}
}
protected BlockingQueue m_list;
protected Thread m_thread;
}
I am trying to make this as modular as possible, let's suppose for example that I would like to add a ".doc" processing, I'd have to do a check inside the manager and implement another DOCProcessor.
How could I do this without the modification of ProcessingManager? and I really don't know if my manager is ok enough, please tell me all your suggestions on this.
I'm not really aware of your problem but I'll try to give it a shot.
You could be using the Factory pattern.
class FileProcessorFactory {
public FileProcessor getFileProcessor(string extension){
switch (extension){
case ".pdf":
return new PdfFileProcessor();
case ".xls":
return new ExcelFileProcessor();
}
}
}
class IFileProcessor{
public Object processFile(Stream inputFile);
}
class PdfFileProcessor : IFileProcessor {
public Object processFile(Stream inputFile){
// do things with your inputFile
}
}
class ExcelFileProcessor : IFileProcessor {
public Object processFile(Stream inputFile){
// do things with your inputFile
}
}
This should make sure you are using the FileProcessorFactory to get the correct processor, and the IFileProcessor will make sure you're not implementing different things for each processor.
and implement another DOCProcessor
Just add a new case to the FileProcessorFactory, and a new class which implements the interface IFileProcessor called DocFileProcessor.
You could decorate your processors with custom attributes like this:
[FileProcessorExtension(".doc")]
public class DocProcessor()
{
}
Then your processing manager could find the processor whose FileProcessorExtension property matches your extension, and instantiate it reflexively.
I agree with Highmastdon, his factory is a good solution. The core idea is not to have any FileProcessor implementation reference in your ProcessingManager anymore, only a reference to IFileProcessor interface, thus ProcessingManager does not know which type of file it deals with, it just knows it is an IFileProcessor which implements processFile(Stream inputFile).
In the long run, you'll just have to write new FileProcessor implementations, and voila. ProcessingManager does not change over time.
Use one more method called CanHandle for example:
abstract class FileProcessor
{
public FileProcessor()
{
}
public abstract Process(string path);
public abstract bool CanHandle(string path);
}
With excel file, you can implement CanHandle as below:
class Excelprocessor: FileProcessor
{
public override void Process(string path)
{
}
public override bool CanHandle(string path)
{
return path.EndsWith(".xlsx");
}
}
In ProcessingManager, you need a list of processor which you can add in runtime by method RegisterProcessor:
class ProcessingManager
{
private List<FileProcessor> _processors;
public void RegisterProcessor(FileProcessor processor)
{
_processors.Add(processor)
}
....
So LINQ can be used in here to find appropriate processor:
while(some_condition)
{
string fPath= _this.m_list.Dequeue();
var proccessor = _processors.SingleOrDefault(p => p.CanHandle(fPath));
if (proccessor != null)
proccessor.Process(proccessor);
}
If you want to add more processor, just define and add it into ProcessingManager by using
RegisterProcessor method. You also don't change any code from other classes even FileProcessorFactory like #Highmastdon's answer.
You could use the Factory pattern (a good choice)
In Factory pattern there is the possibility not to change the existing code (Follow SOLID Principle).
In future if a new Doc file support is to be added, you could use the concept of Dictionaries. (instead of modifying the switch statement)
//Some Abstract Code to get you started (Its 2 am... not a good time to give a working code)
1. Define a new dictionary with {FileType, IFileProcessor)
2. Add to the dictionary the available classes.
3. Tomorrow if you come across a new requirement simply do this.
Dictionary.Add(FileType.Docx, new DocFileProcessor());
4. Tryparse an enum for a userinput value.
5. Get the enum instance and then get that object that does your work!
Otherwise an option: It is better to go with MEF (Managed Extensibility Framework!)
That way, you dynamically discover the classes.
For example if the support for .doc needs to be implemented you could use something like below:
Export[typeof(IFileProcessor)]
class DocFileProcessor : IFileProcessor
{
DocFileProcessor(FileType type);
/// Implement the functionality if Document type is .docx in processFile() here
}
Advantages of this method:
Your DocFileProcessor class is identified automatically since it implements IFileProcessor
Application is always Extensible. (You do an importOnce of all parts, get the matching parts and Execute.. Its that simple!)

How can I return a ReadOnly object class with mutable properties while allowing write access

I've got quite a number of classes, which have got the standard set and get methods. My problem is that many of these set methods should not be callable from outside the class which holds the objects. I'm not quite sure if there are any patterns or C# for lack of a better word - operations that would make this easier.
In reference to the code below, there are a number of classes similar to SecureSite, which the controller should be able to call functions or access variables to modify the SecureSite (and the other similar classes). However when the user asks to see SecureSite etc. they shouldn't be able to change this.
From my limited knowledge and the answers I've seen to similar questions on this site, the main issue appears to be that the Write_SecureSite can't be made fully immutable due to the List<String> AccessHistory variable. So, what I've come up with looks as ugly as a bulldogs backside and is just as messy. Essentially there is a Write version of the SecureSite class which contains a class within it, which returns a readonly version of the SecureSite class.
So, am I missing something magic in C# that would make this all so much easier?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ReadOnlyExample {
public class Write_SecureSite {
private List<String> mAccessHistory;
public List<String> AccessHistory {
get {
return mAccessHistory;
}
}
public SecureSite ReadOnly {
get {
return new SecureSite(this);
}
}
public class SecureSite {
public SecureSite(Write_SecureSite aParent) {
AccessHistory=aParent.AccessHistory;
}
public IEnumerable<String> AccessHistory;
}
}
public static class Controller {
private static Write_SecureSite SimpleSecureSite=new Write_SecureSite();
public static Write_SecureSite.SecureSite Login(String MyLogin) {
SimpleSecureSite.AccessHistory.Add(MyLogin);
return SimpleSecureSite.ReadOnly;
}
public static Write_SecureSite.SecureSite Details() {
return SimpleSecureSite.ReadOnly;
}
}
public static class User {
public static void Miscellaneous() {
Controller.Login("Me");
Write_SecureSite.SecureSite SecureSite=Controller.Details();
//Not going to happen.
SecureSite.AccessHistory.Add("Me2");
//No problem.
foreach(String AccessedBy in SecureSite.AccessHistory) {
Console.Out.WriteLine("Accessed By: "+AccessedBy);
}
}
}
}
I suggest to use interfaces:
public interface IReadSecureSite
{
IEnumerable<String> AccessHistory { get; }
}
class Write_SecureSite : IReadSecureSite
{
public IList<String> AccessHistoryList { get; private set; }
public Write_SecureSite()
{
AccessHistoryList = new List<string>();
}
public IEnumerable<String> AccessHistory {
get {
return AccessHistoryList;
}
}
}
public class Controller
{
private Write_SecureSite sec= new Write_SecureSite();
public IReadSecureSite Login(string user)
{
return sec;
}
}
...
Controller ctrl = new Controller();
IReadSecureSite read = ctrl.Login("me");
foreach(string user in read.AccessHistory)
{
}
This is not so much an answer as a direction to look into. I am also struggling with the Immutable class
So far I am using my constructors to set my read-only private vars
I am using methods to update my lists internally instead of exposing them as public properties: ie. use public Void Add(string itemToAdd)
I am reading a book by Petricek and Skeet called "Real World Functional Programming" and it is helping me move in the direction you are discussing
Here is a small tutorial from the same author's that introduces some basic concepts: http://msdn.microsoft.com/en-us/library/hh297108.aspx
Hope this helps a bit
Update: I probably should have been clearer: I was looking to point you in the direction of a more functional view as opposed to rewriting the class you had listed in your question - my apologies (removed sample)

Service doesn't implement Property's get/set method

I'm having trouble with the Service Reference Manager in my Silverlight application substituting the get and set methods of a property with a generic one.
My example: I have a Rule class in my Service that has three public properties that all use the same private member.
[DataContract]
public class RulesReadable
{
[DataMember]
private bool? m_passed;
...
[DataMember]
public bool? State
{
get { return m_passed; }
set { m_passed = value; }
}
[DataMember]
public bool HasPassed
{
get { return (m_passed == true) ? true : false; }
set { m_passed = value; }
}
[DataMember]
public bool HasFailed
{
get { return (m_passed == false) ? true : false; }
set { m_passed = !value; }
}
}
When I call the service, get this data type back, and try to get/set the properties I find that each property has been given its own variable instead of sharing one between the three. If I go to the definition of the class on the Silverlight side I see that this is in fact what has happened:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="Manager.RulesReadable", Namespace="http://schemas.datacontract.org/2004/07/MyWebApp.Services")]
public partial class ManagerRulesReadable : object, System.ComponentModel.INotifyPropertyChanged {
private bool HasFailedField;
...
[System.Runtime.Serialization.DataMemberAttribute()]
public bool HasFailed {
get {
return this.HasFailedField;
}
set {
if ((this.HasFailedField.Equals(value) != true)) {
this.HasFailedField = value;
this.RaisePropertyChanged("HasFailed");
}
}
}
...
}
How do I get the class on the Silverlight side to behave like the class on the Service side?
First add the assemblies that these classes are in as references to your Silverlight project. When creating your service reference select the "Reuse types in referenced assemblies" checkbox and either reuse all referenced assemblies or pick and choose specific assemblies to reuse. The assemblies that are referenced by the service directly (and any dependencies) will then be a part of the Silverlight application as well.
Don't use Service References. They are evil. If you google "Silverlight WCF without Service Reference" you will find several good tutorials.

Categories