开发者

Auto-generate a Wrapper class in C# using Composition

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.Proper开发者_如何学JAVAty3; } 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.

  1. add the interface to the class you wish to be the wrapping class

    class MyWebElement : IWebElement { }
    

  1. Find/Click "Delegate implementation of "YourInterfaceHere" to a new field

    Auto-generate a Wrapper class in C# using Composition


  1. Select your options

    Auto-generate a Wrapper class in C# using Composition


  1. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜