Inheritance Fluent Builder with reference back to parent? - c#

Not sure I am doing this correctly but essentially I have an object Foo which has heaps of configurations. I am using the Fluent Builder pattern to set the params as it makes it easier to mix & match. Once the parameters are set I wish to essentially "run" the analysis...
The complication is with the Bar object which is a slightly different calculation method uses a combined set of the Foo params + Bar params.
My initial thoughts is to have an abstract calculation class BaseCalc which contains common calculations and set either FooCalc or BarCalc which contains the custom calculations depending if AddBar is called.
analysis = new FooBuilder()
.SetData(data)
.SetParam1("Foo")
.AddBar(builder => builder
.SetParam2("Bar")
)
.Build();
public class FooBuilder: IFooBuilder
{
private readonly Foo foo;
public IFooBuilder SetData(List<int> data)
{
foo.source = data;
return this;
}
public IFooBuilder SetParam1(string param)
{
foo.param1 = param;
return this;
}
public IFooBuilder(AddBar(Action<IBarBuilder> configure)
{
var builder = new BarBuilder();
configure(builder);
foo.Bar = builder.Build();
return this;
}
}
public abstract class BaseCalc
{
public abstract void Run();
}
public class FooCalc : BaseCalc
{
public override void Run()
{
Console.WriteLine("This should be Param1 Foo");
}
}
public class BarCalc : BaseCalc
{
public override void Run()
{
Console.WriteLine("This should be Param1 Foo + Param2 Bar");
}
}
As an example if I called analysis.Run() in the example above it would run BarCalc.Run() using both Foo and Bar

Related

How to pass 2 different types into a function param in c#?

In c# if I have this
private void Run(Web site) {
site.BreakRoleInheritance(false, false);
}
private void Run(ListItem folder) {
folder.BreakRoleInheritance(false, false);
}
How can I instead make 1 function that can accept either Site or Folder?
If Site and Folder are classes that you've created, then you can create a common interface which those classes inherit from. For example:
public interface IBreakable
{
void break();
}
public class Folder : IBreakable
{
public void break() { /* implementation here*/ }
}
public class Site : IBreakable
{
public void break() { /* implementation here*/ }
}
Usage
private void Run(IBreakable breakable)
{
breakable.break();
}
Edit
Here's a solution based on reflection, although this is not ideal.
void Run(object obj)
{
MethodInfo method = obj.GetType().GetMethod("break");
if (!(method is null))
{
method.Invoke(obj, new object[] {});
}
}
Given
public class Foo
{
public void break() {Console.WriteLine("Foo");}
}
public class Bar
{
public void break() {Console.WriteLine("Bar");}
}
public class Bad
{
public void NotBreak() {Console.WriteLine("Bad");}
}
Usage
Foo foo = new Foo();
Bar bar = new Bar();
Bad bad = new Bad();
Run(foo);
Run(bar);
Run(bad);
Output
Foo
Bar
As a later answer from #Pedro pointed out, those specific classes derive from a common ancestor, and that would be the preferred option. Assuming you did not have that option:
You can use the C# dynamic type (sorry if that is not the latest doc, I couldn't find a newer one):
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/using-type-dynamic
Example:
using System;
public class Program
{
public static void Main()
{
var foo = new Foo();
var bar = new Bar();
DoSomething(foo);
DoSomething(bar);
}
private static void DoSomething<T>(T someObjectWithDoMethod)
{
((dynamic)someObjectWithDoMethod).Do();
}
}
public class Foo
{
public void Do() { Console.WriteLine("Foo is doing something"); }
}
public class Bar
{
public void Do() { Console.WriteLine("Bar is doing something"); }
}
.Net Fiddle: https://dotnetfiddle.net/MShLK5
Based on your comments to other answers, Web and ListItem are types defined in the Microsoft.SharePoint.Client.
Checking the SDK docs, both types derive from SecurableObject where the BreakRoleInheritance method is defined.
That being the case, all you need to do is define one method that takes a SecurableObject object as an input:
public void Run(SecurableObject item)
{
item.BreakRoleInheritance();
}
And you should be able to pass a Web and a ListItem to this same method.

Composite pattern of sealed class that has no interface

Let's say that I am using a library that I have no control over whatsoever. This library exposes service that requires argument of certain class. Class is marked as sealed and has no interface.
tl;dr: How can I reimplement sealed class as interface?
Code example:
using System;
namespace IDontHaveControlOverThis
{
// Note no interface and the class is being sealed
public sealed class ArgumentClass
{
public String AnyCall() => "ArgumentClass::AnyCall";
}
public sealed class ServiceClass
{
public String ServiceCall(ArgumentClass argument) => $"ServiceClass::ServiceCall({argument.AnyCall()})";
}
}
namespace MyCode
{
// Composite pattern, basically I need: "is a ArgumentClass"
// Obviously doesn't work - can't extend from sealed class
public class MyArgumentClass : IDontHaveControlOverThis.ArgumentClass
{
private IDontHaveControlOverThis.ArgumentClass arg = new IDontHaveControlOverThis.ArgumentClass();
public String AnyCall() => $"MyArgumentCLass::AnyCall({arg.AnyCall()})";
}
}
public class Program
{
public static void Main()
{
// I don't have control over this
IDontHaveControlOverThis.ServiceClass service = new IDontHaveControlOverThis.ServiceClass();
//This obviously works
IDontHaveControlOverThis.ArgumentClass arg = new IDontHaveControlOverThis.ArgumentClass();
Console.WriteLine($"Result: {service.ServiceCall(arg)}");
// How to make this work?
IDontHaveControlOverThis.ArgumentClass myArg = new MyCode.MyArgumentClass();
Console.WriteLine($"Result: {service.ServiceCall(myArg)}");
}
}
Based on the code sample you show, the answer is you can't. You need to be able to modify the behavior of IDontHaveControlOverThis.ArgumentClass, by setting a property, or creating a new instance with different constructor parameters in order to modify the servicecall. (It now always returns the same string, so the servicecall is always the same)
If you are able to modify the behavior of the ArgumentClass by setting properties.
You could create wrappers for the sealed classes in your own code, and use that throughout your codebase.
public class MyArgumentClass
{
// TODO: Set this to a useful value of ArgumentClass.
internal IDontHaveControlOverThis.ArgumentClass InnerArgumentClass { get; }
public virtual string AnyCall() => "???";
}
public class MyServiceClass
{
private IDontHaveControlOverThis.ServiceClass innerServiceClass
= new IDontHaveControlOverThis.ServiceClass();
public virtual string ServiceCall(MyArgumentClass argument)
{
return innerServiceClass.ServiceCall(argument.InnerArgumentClass);
}
}
or
public class MyArgumentClass
{
public virtual string AnyCall() => "???";
}
public class MyServiceClass
{
private IDontHaveControlOverThis.ServiceClass innerServiceClass
= new IDontHaveControlOverThis.ServiceClass();
public string ServiceCall(MyArgumentClass argument)
{
var serviceArgument = Convert(argument);
return innerServiceClass.ServiceCall(serviceArgument);
}
private IDontHaveControlOverThis.ArgumentClass Convert(MyArgumentClass argument)
{
// TODO: implement.
}
}
The compiler error message
Cannot implicitly convert type 'MyCode.MyArgumentClass' to 'IDontHaveControlOverThis.ArgumentClass'
note: emphasis mine
should give you a hint as to what you can do
public class MyArgumentClass {
private IDontHaveControlOverThis.ArgumentClass arg = new IDontHaveControlOverThis.ArgumentClass();
public String AnyCall() => $"MyArgumentCLass::AnyCall({arg.AnyCall()})";
public static implicit operator IDontHaveControlOverThis.ArgumentClass(MyArgumentClass source) {
return source.arg;
}
}
So now your "wrapper" exposes the 3rd party dependency as needed
IDontHaveControlOverThis.ArgumentClass myArg = new MyCode.MyArgumentClass();
or directly
var myArg = new MyCode.MyArgumentClass();
Console.WriteLine($"Result: {service.ServiceCall(myArg)}");
Reference User-defined conversion operators (C# reference)
Which can allow for abstracting your code
namespace MyCode {
public interface IMyService {
String ServiceCall(MyArgumentClass argument);
}
public class MyServiceClass : IMyService {
public string ServiceCall(MyArgumentClass argument) {
IDontHaveControlOverThis.ServiceClass service = new IDontHaveControlOverThis.ServiceClass();
return service.ServiceCall(argument);
}
}
}

How to use an interface within a public interface with a main?

//Program.cs
public interface TestVal
{
//Input Param
string Input { get; }
//will return output
TestValRes ValidateRe(string input);
}
class MyClass : ITestVal
{
static void Main(string[] args)
{
var instance = new MyClass();
instance.Run();
}
public void Run()
{
ValidateRe("test");
}
public ITestValRes ValidateRe(string input)
{
return null; // return an instance of a class implementing ITestValRes here.
}
}
//TestvalRes.cs
public interface TestvalRes
{
string Input { get; }
bool IsValid { get; }
}
So I just want to pass a string to the TestVal, do validation and call TestvalRes to return whether it is Valid or not, and if Invalid, why? So the validation will be done in the first public interface - TestVal, however I still need to call it inside the Main(), right?
First off, I'd recommend following C# naming conventions and name your interfaces ITestVal and ITestValRes respectively.
Next, static method cannot call instance methods in the same class (without creating an instance and using that). You need to create an instance of the class and pass control of the application flow to that:
class MyClass : ITestVal
{
static void Main(string[] args)
{
var instance = new MyClass();
instance.Run();
}
public void Run()
{
ValidateRe("test");
}
public ITestValRes ValidateRe(string input)
{
return null; // return an instance of a class implementing ITestValRes here.
}
}

Automatic creation of constructors in C#

I'm just wondering if there's an automated way to generate constructors with every possible combination of the parameters you might need.
I have a ctor with 4 parameters, but I want to provide overloads where a developer could pass in a single param, or two or three. By hand I've been writing every possible combination and passing defaults to the 4 parameter one. I also need to then introduce two more "full" prototypes ( with a fifth ), then create all the possible combinations for those as well, so I need loads of ctor overloads to cover all combinations.
I'd like to manually write the three full ctors, then be able to generate the combinations with a context menu click. I haven't seen an option like this in Resharper. Anyone know if there's an existing solution out there already?
If you need a lot of constructor parameters, rather than struggling with the explosion of possible permutations, consider creating an "options" class that has sensible defaults:
public class FooOptions
{
public FooOptions()
{
MaintenanceInterval = TimeSpan.FromSeconds(30);
MaximumIdleTime = TimeSpan.FromMinutes(5);
}
public TimeSpan MaintenanceInterval { get; set; }
public TimeSpan MaximumIdleTime { get; set; }
//etc...
}
then
class Foo
{
public Foo():this(new FooOptions())
{
}
public Foo(FooOptions opts)
{
//...
}
}
This situation would be a perfect fit for the Builder pattern.
For example, if the class Foo can have any combination of a String, an int and a Bar:
public class Foo
{
public string MyString { get; set; }
public int MyInt { get; set; }
public Bar MyBar { get; set; }
}
Instead of adding a constructor with every possibility, make a Builder. Here's an example of a simple fluent implementation:
public class FooBuilder
{
private Foo foo = new Foo();
public FooBuilder WithString(String someString)
{
foo.MyString = someString;
return this;
}
public FooBuilder WithInt(int someInt)
{
foo.MyInt = someInt;
return this;
}
public FooBuilder WithBar(Bar someBar)
{
foo.MyBar = someBar;
return this;
}
public Foo Build()
{
return foo;
}
}
which can be used like this:
Foo foo = new FooBuilder().WithString("abc").WithInt(3).Build();
This eliminates completely the need for an exponential number of constructors.
Don't need multiple constructor overloads - try using optional/default parameters. Relevant link: https://msdn.microsoft.com/en-us/library/dd264739.aspx
Example code:
class Program
{
static void Main(string[] args)
{
var defaultMonster = new Monster();
var archerMonster = new Monster("crossbow");
var knightMonster = new Monster("broadsword", "plate mail");
var wizardMonster = new Monster(armor: "wizard robe", magicItem: "wand");
Console.WriteLine(defaultMonster);
Console.WriteLine(archerMonster);
Console.WriteLine(knightMonster);
Console.WriteLine(wizardMonster);
}
}
class Monster
{
private readonly string _weapon;
private readonly string _armor;
private readonly string _magicItem;
public Monster(string weapon = "scimitar", string armor = "leather", string magicItem = "nothing")
{
_weapon = weapon;
_armor = armor;
_magicItem = magicItem;
}
public override string ToString()
{
return string.Format("Monster armed with {0}, wearing {1}, carrying {2}", _weapon, _armor, _magicItem);
}
}

Moq - Checking method call on concrete class

Here is a very simplistic example of what I'm trying to do:
public class Bar
{
public void SomeMethod(string param)
{
//whatever
}
}
public interface IBarRepository
{
List<Bar> GetBarsFromStore();
}
public class FooService
{
private readonly IBarRepository _barRepository;
public FooService(IBarRepository barRepository)
{
_barRepository = barRepository;
}
public List<Bar> GetBars()
{
var bars = _barRepository.GetBarsFromStore();
foreach (var bar in bars)
{
bar.SomeMethod("someValue");
}
return bars;
}
}
In my test, I'm mocking IBarRepository to return a concrete List defined in the unit test and passing that mocked repository instance to the FooService constructor.
I want to verify in the FooService method GetBars that SomeMethod was called for each of the Bars returned from the repository. I'm using Moq. Is there any way to do this without mocking the list of Bars returned (if even possible) and not having to put some hacky flag in Bar (yuck) ?.
I'm following an example from a DDD book, but I'm starting to think it smells because I'm challenged in testing the implementation....
Revised... this passes:
public class Bar
{
public virtual void SomeMethod(string param)
{
//whatever
}
}
public interface IBarRepository
{
List<Bar> GetBarsFromStore();
}
public class FooService
{
private readonly IBarRepository _barRepository;
public FooService(IBarRepository barRepository)
{
_barRepository = barRepository;
}
public List<Bar> GetBars()
{
var bars = _barRepository.GetBarsFromStore();
foreach (var bar in bars)
{
bar.SomeMethod("someValue");
}
return bars;
}
}
[TestMethod]
public void Verify_All_Bars_Called()
{
var myBarStub = new Mock<Bar>();
var mySecondBarStub = new Mock<Bar>();
var myBarList = new List<Bar>() { myBarStub.Object, mySecondBarStub.Object };
var myStub = new Mock<IBarRepository>();
myStub.Setup(repos => repos.GetBarsFromStore()).Returns(myBarList);
var myService = new FooService(myStub.Object);
myService.GetBars();
myBarStub.Verify(bar => bar.SomeMethod(It.IsAny<string>()), Times.Once());
mySecondBarStub.Verify(bar => bar.SomeMethod(It.IsAny<string>()), Times.Once());
}
Note the slight change to class Bar (SomeMethod() is virtual). A change, but not one involving a flag... :)
Now, in terms of broader design, there is some mutation going on with your bar (whatever "SomeMethod()" actually does). The best thing to do would probably be to verify that this mutation happened on each Bar returned from FooService.GetBars(). That is, setup your repository stub to return some bars, and then verify that whatever mutation is performed by SomeMethod() has taken place. After all, you control the Bars that will be returned, so you can setup their pre-SomeMethod() state, and then inspect their post-SomeMethod() state.
If I was writing these classes with unit testing in mind, I would likely either have the class Bar implement an interface IBar and use that interface in my service, or make SomeMethod virtual in Bar.
Ideally like this:
public interface IBar
{
void SomeMethod(string param);
}
public class Bar : IBar
{
public void SomeMethod(string param) {}
}
public interface IBarRepository
{
List<IBar> GetBarsFromStore();
}
public class FooService
{
private readonly IBarRepository _barRepository;
public FooService(IBarRepository barRepository)
{
_barRepository = barRepository;
}
public List<IBar> GetBars()
{
var bars = _barRepository.GetBarsFromStore();
foreach (var bar in bars)
{
bar.SomeMethod("someValue");
}
return bars;
}
}
Then my unit test would look as follows:
[Test]
public void TestSomeMethodCalledForEachBar()
{
// Setup
var barMocks = new Mock<IBar>[] { new Mock<IBar>(), new Mock<IBar>() };
var barObjects = barMocks.Select(m => m.Object);
var repoList = new List<IBar>(barsObjects);
var repositoryMock = new Mock<IBarRepository>();
repositoryMock.Setup(r => r.GetBarsFromStore()).Returns(repoList);
// Execute
var service = new FooService(repositoryMock.Object);
service.GetBars();
// Assert
foreach(var barMock in barMocks)
barMock.Verify(b => b.SomeMethod("someValue"));
}

Categories