How to ensure the sequence of methods in fluent API? - c#

I want to create fluent interface for some of my classes that I am building as part of a framework. I have created the methods and I am able to successfully chain methods. Now I want to ensure that I can handle the improper sequence of method calls.
The thing I am doing is something like CreateWorkflow -> OpenConfiguration -> ChangeUserName
In the above scenario it wouldn't make sense if ChangeUserName was called first because it is dependent on OpenConfiguration.
I am confused whether I am correct in creating a Fluent chain of methods for this scenario or not and how to make the sequence work. To me this scenario seems to be very suitable for creating a fluent API.

Here is the sample code that enforces method chain in specific order. I've used the example from here and fixed a minor issue in the original code. Here is the running code in dotnet fiddler
public interface IName
{
IAge WithName(string name);
}
public interface IAge
{
IPersist WithAge(int age);
}
public interface IPersist
{
void Save();
}
public class Person : IName, IAge, IPersist
{
public string Name { get; private set; }
public int Age { get; private set; }
public IAge WithName(string name)
{
Name = name;
return this;
}
public IPersist WithAge(int age)
{
Age = age;
return this;
}
public void Save()
{
// save changes here
}
}

The real key is if you require a specific sequence for a fluent API to work you API needs improvement. Maybe you should consider something a little different. If ChangeUserName needs OpenConfiguration the consumer of the API shouldn't care. Either internalize the dependency so the API becomes:
CreateWorkflow -> ChangeUserName
or if the consumer already has the Configuration Object you could use a Dependency Injection approach and make the API something like:
CreateWorkflow(IConfigurationManager) -> ChangeUserName
or
CreateWorkflow -> ChangeUserName(IConfigurationManager)
I show 2 approaches here as I am not sure what the scope of dependency is on your configuration class. By either internalizing the need or adding a required parameter onto the signature of one of the methods you should be able to eliminate the fixed sequence issue. Other than a clear "Start" and "Finish" to your API.
Hope this helps.

Related

Unit testing extension methods, had a go, is this right, or gone around the houses?

I have my POCO library and i have entities that implement an interface called IEntityDelete.
Interface is very simple, looks something like this
public interface IEntityDelete
{
bool IsDeleted { get; set; }
}
So i have an entity that implements this interface, again very simple, looks something like this
public class MyEntity() : IEntityDelete
{
public bool IsDeleted { get; set; }
}
I have an extension method, which i created this like
public static void MarkAsDeleted(this IEntityDelete entity)
{
entity.IsDeleted = true;
}
Then i needed to check if this method was being called within one of my service methods in my unit tests. Service method is very basic, looks something like this.
public Task<int> DeleteByFlagAsync(MyEntity entity)
{
entity.MarkAsDeleted();
return _context.SaveChangesAsync();
}
Apparently you cannot test extension methods easily, without using Microsofts Moles framework, but i do not want another dependency.
I did some googl'ing and found 2 articles on this, and how to do about it, and would like to know if this is correct, or whether i have done something stupid.
Two articles i found where
http://adventuresdotnet.blogspot.co.uk/2011/03/mocking-static-methods-for-unit-testing.html
http://blogs.clariusconsulting.net/kzu/how-to-mock-extension-methods/
They recommend using a wrapper class which aint static, so i ended up with this.
First created my wrapper interface
public interface IEntityDeleteWrapper
{
void MarkAsDeleted(IEntityDelete entity);
}
Create a class that implements this interface
public class EntityDeleteWrapper : IEntityDeleteWrapper
{
public void MarkAsDeleted(IEntityDelete entity)
{
entity.IsDeleted = true;
entity.DeletedDate = DateTime.Now;
entity.DeletedByUserId = 546372819;
}
}
Inject this interface into my service constructor
public MyService(IEntityDeleteWrapper deleteWrapper)
{
_deleteWrapper = deleteWrapper;
}
Change my service method call to use the wrapper like so
public Task<int> DeleteByFlagAsync(MyEntity entity)
{
_deleteWrapper.MarkAsDeleted(entity);
return _context.SaveChangesAsync();
}
SOLVED
As i was told, this was way too far to go, i can just check if a property has changed. In light of this, i am using my extension method still and updated my unit test to this.
[TestMethod]
public void should_mark_entity_as_deleted()
{
// arrange
var entity = new Attachment
{
IsDeleted = false
};
// act
var result = _service.DeleteByFlagAsync(entity).Result;
// assert
Assert.AreEqual(true, entity.IsDeleted);
_context.Verify(e => e.SaveChangesAsync(), Times.Once);
}
You went too far. Your test should verify observable change to state, not how that change was made. Otherwise you make your tests very brittle, not to mention you add rather unnecessary extra layer. It would be enough to check whether entity properties changed after DeleteByFlagAsync call.
Of course, when deleting gets more complex introducing dependency to delegate this task to makes sense. But then, few questions arise:
What would be the scope of DeleteByFlagAsync? Call two dependencies?
Would it be practical to test it?
...or perhaps tests for said dependency would suffice (as this is where the actual mark-for-deletion will take place)?

How to add support for xunit's Theory attribute in Approvaltests

When I try to use approvals with my unit test decorated with [Theory] attribute it says:
System.Exception: System.Exception : Approvals is not set up to use your test framework.
It currently supports [NUnit, MsTest, MbUnit, xUnit.net]
To add one use ApprovalTests.StackTraceParsers.StackTraceParser.AddParser() method to add implementation of ApprovalTests.StackTraceParsers.IStackTraceParser with support for your testing framework.
To learn how to implement one see http://blog.approvaltests.com/2012/01/creating-namers.html
at ApprovalTests.StackTraceParsers.StackTraceParser.Parse(StackTrace stackTrace)
at ApprovalTests.Namers.UnitTestFrameworkNamer..ctor()
at ApprovalTests.Approvals.GetDefaultNamer()
at ApprovalTests.Approvals.Verify(IApprovalWriter writer)
at ApprovalTests.Approvals.Verify(Object text)
Seems like it recognizes [Fact] attributes only. I tried to follow the link from stacktrace but there is nothing about how to plug in your own namer/parser into approvals.
Is there any entry point where I can add my own namer/parser? Itself it seems to be trivial, the only question is how to use it:
public class TheoryNamer : AttributeStackTraceParser
{
protected override string GetAttributeType()
{
return typeof(TheoryAttribute).FullName;
}
public override string ForTestingFramework
{
get { return "xUnit Extensions"; }
}
}
There are a couple parts to this answer & question.
How to add
The Namer
Dealing with data driven tests in approvaltests
1) How to add
Adding is simple (if a bit rough)
The method mentioned should have been static, but it works none the less.
To add one use
ApprovalTests.StackTraceParsers.StackTraceParser.AddParser() method to
add implementation of
ApprovalTests.StackTraceParsers.IStackTraceParser with support for
your testing framework.
so you'll need to do a
new StackTraceParser().AddParser(new TheoryNamer());
I apologize for this, and it will be static in the next version (v.21)
2) The Namer
The Namer is suppose to generate a unique name for each approved/received file. This is normally done on the name of the method, however the name here will not be unique as a theory based test will be data driven and therefore have multiple calls to the same method.
Naming: classname.methodname(optional: .additionalInformation).received.extension
As such, you will probably have to include additional information in the method it's self
public class StringTests1
{
[Theory,
InlineData("goodnight moon"),
InlineData("hello world")]
public void Contains(string input)
{
NamerFactory.AdditionalInformation = input; // <- important
Approvals.Verify(transform(input));
}
}
3) Dealing with data driven tests in approvaltests
To be honest, in most cases, the data driven method of approach in Approval Tests isn't thru parameters in the Method Decorators. It is usually thru the VerifyAll with a lambda transform. For Example the above might look like
[Fact]
public void UpperCase()
{
var inputs = new[]{"goodnight moon","hello world"};
Approvals.VerifyAll(inputs, i => "{0} => {1}".FormatWith(i, i.ToUpperInvariant()));
}
Which would create the received file:
goodnight moon => GOODNIGHT MOON
hello world => HELLO WORLD
It's better to inherit TheoryNamer class from XUnitStackTraceParser.
It works perfect!
I think it would be cool to add such class into ApprovalTests.StackTraceParsers namespace :)
public class XUnitTheoryStackTraceParser : XUnitStackTraceParser
{
public const string TheoryAttribute = "Xunit.Extensions.TheoryAttribute";
protected override string GetAttributeType()
{
return TheoryAttribute;
}
}
public class ApproveTheoryTest
{
static ApproveTheoryTest()
{
StackTraceParser.AddParser(new XUnitTheoryStackTraceParser());
}
[Theory]
[UseReporter(typeof(DiffReporter))]
[InlineData("file1.txt")]
[InlineData("file2.txt")]
public void approve_file(string fileName)
{
NamerFactory.AdditionalInformation = fileName;
Approvals.Verify("sample text");
}
}

Can I use more generic interfaces to simplify my classes to use a command pattern?

I'm trying to make an app I'm designing more generic and implement the command pattern into it to use manager classes to invoke methods exposed by interfaces.
I have several classes with the GetItem() and GetList() methods in them, some are overloaded. They accept different parameters as I was trying to use dependency injection, and they return different types. Here are a couple of examples:
class DatastoreHelper
{
public Datastore GetItem(string DatastoreName)
{
// return new Datastore(); from somewhere
}
public Datastore GetItem(int DatastoreID)
{
// return new Datastore(); from somewhere
}
public List<Datastore> GetList()
{
// return List<Datastore>(); from somewhere
}
public List<Datastore> GetList(HostSystem myHostSystem)
{
// return List<Datastore>(); from somewhere
}
}
class HostSystemHelper
{
public HostSystem GetItem(int HostSystemID)
{
// return new HostSystem(); from somewhere
}
public List<HostSystem> GetList(string ClusterName)
{
//return new List<HostSystem>(); from somewhere
}
}
I'm trying to figure out if I could use a generic interface for these two methods, and a manager class which would effectively be the controller. Doing this would increase the reuse ability of my manager class.
interface IGetObjects
{
public object GetItem();
public object GetList();
}
class GetObjectsManager
{
private IGetObjects mGetObject;
public GetObjectsManager(IGetObjects GetObject)
{
this.mGetObject = GetObject;
}
public object GetItem()
{
return this.mGetObject.GetItem();
}
public object GetList()
{
return this.GetList();
}
}
I know I'd have to ditch passing in the parameters to the methods themselves and use class properties instead, but I'd lose the dependency injection. I know I'd have to cast the return objects at the calling code into what they're supposed to be. So my helper classes would then look like this:
class DatastoreHelper
{
public string DatastoreName { get; set; }
public string DatastoreID { get; set; }
public object GetItem()
{
// return new Datastore(); from somewhere
}
public List<object> GetList()
{
// return List<Datastore>(); from somewhere
}
}
class HostSystemHelper
{
public int HostSystemID { get; set; }
public string ClusterName {get; set;}
public object GetItem()
{
// return new HostSystem(); from somewhere
}
public List<object> GetList()
{
//return new List<HostSystem>(); from somewhere
}
}
But is the above a good idea or am I trying to fit a pattern in somewhere it doesn't belong?
EDIT: I've added some more overloaded methods to illustrate that my classes are complex and contain many methods, some overloaded many times according to different input params.
If I understand the concept correctly, a design like this is a really bad idea:
class DatastoreHelper
{
public string DatastoreName { get; set; }
public string DatastoreID { get; set; }
public object GetItem()
{
// return new Datastore(); from somewhere
}
public List<object> GetList()
{
// return List<Datastore>(); from somewhere
}
}
The reason is that getting results would now be a two-step process: first setting properties, then calling a method. This presents a whole array of problems:
Unintuitive (everyone is used to providing parameters as part of the method call)
Moves the parameter binding away from the call site (granted, this would probably mean "moves them to the previous LOC", but still)
It's no longer obvious which method uses which property values
Take an instance of this object and just add a few threads for instant fun
Suggestions:
Make both IGetObjects and GetObjectsManager generic so that you don't lose type safety. This loses you the ability to treat different managers polymorphically, but what is the point in that? Each manager will be in the end specialized for a specific type of object, and unless you know what that type is then you cannot really use the return value of the getter methods. So what do you stand to gain by being able to treat managers as "manager of unknown"?
Look into rewriting your GetX methods to accept an Expression<Func<T, bool>> instead of bare values. This way you can use lambda predicates which will make your code massively more flexible without really losing anything. For example:
helper.GetItem(i => i.DataStoreID == 42);
helper.GetList(i => i.DataStoreName.Contains("Foo"));
The first code samples look quite similar to the Repository Pattern. I think this is what are you trying to apply. The last sample is not good and Jon told you why. However, instead of reinventing the wheel, read a bit about the Repository (lots of questions about it on SO) because, if I understood correctly, this is what you really want.
About reuse, not many things and especially persistence interface are reusable. There is the Generic Repository Pattern (I consider it an anti-pattern) which tries to accomplish that but really, do all the application needs the same persistence interface?
As a general guideline, when you design an object, design it to fullfil the specific application needs, if it happens to be reused that's a bonus, but that's not a primary purpose of an object.
It is not a good idea. Based on these examples you would be better off with a generic interface for the varying return type and parameters of GetItem/GetList. Though honestly the prevalence of Managers, the use of something cas vague as GetItem in multiple places and trying to fit your solution into design patterns (rather than defining the solution in terms of the patterns) are huge code smells to me for the wider solution.

How do I convert one object to another?

I have an interface named IDeviceId that I use in my domain. I also have several concrete classes that implement IDeviceId. Each concrete class contains the logic for a specific type of DeviceId. For example, I have DeviceMacId, which is simply a valid MAC address. Another concrete class is DeviceShortMacId, which takes the last 6 digits of a valid MAC address and combines it with a fixed 6-character prefix to create a valid MAC (several legacy apps use only the last 6 digits). I have a few other classes for expressing an ID, but the majority of them are all derivatives of the same data.
I'd like to be able to easily convert from any one of these classes to another. My first thought was to create a static class and do something like DeviceIdConverter.ToDeviceShortMacId(IDeviceId).
What's the best way be able to easily accept data in one form, and then convert it to another in a repeatable fashion (across multiple apps)?
I don't think there is a "best way" to do this, you're going to have to find a pattern that works for you and go with it.
Off the top of my head, based on the examples you presented I would do something like:
interface IDeviceId
{
// Other methods
IDeviceId ToDeviceShortMacId(IDeviceId);
IDeviceId ToDeviceMacId(IDeviceId);
// etc...
}
Then each of the classes would need to implement the conversion methods. Now if you plan on adding a lot of other implementation (concrete) classes later, then this could get pretty verbose. So what you might consider in that case is in each of the projects which creates a new implementation you also create extension methods like:
public static class MacDeviceIdExtensions
{
public static DeviceMacId ToDeviceMacId(this IDeviceId deviceId)
{
// Implement conversion
}
public static DeviceShortMacId ToDeviceMacId(this IDeviceId deviceId)
{
// Implement conversion
}
}
The extension methods approach is a lot more modular, but could also be a lot more code.
One possibility would be to implement your own casting:
public static explicit operator DeviceShortMacId(DeviceMacId deviceMacID)
{
return new DeviceShortMacId(deviceMacID.MacAddress);
}
public static explicit operator DeviceMacId(DeviceShortMacId deviceShortMacID)
{
return new DeviceMacId(deviceShortMacID.MacAddress);
}
That way you can do:
DeviceMacId newDeviceId = (DeviceShortMacId)deviceMacID
With this approach, if some conversions are not possible, you can handle that yourself and throw an InvalidCastException.
Call me old fashioned, but I kind of like the static method approach here. You'll have the conversion logic decoupled from your entities, with a descriptive method name to describe what each conversion does. You might also want to consider implementing them as extension methods.
Why don't you just create constructors on all your IDeviceID implementing classes that accept an IDeviceID object.
DeviceMacID macID = new DeviceMacID(...whatever you do normally...);
DeviceShortMacID shortMacID = new DeviceShortMacID((IDeviceID)macID);
Example code
public DeviceShortMacID : IDeviceID
{
private ID _ID;
public DeviceShortMacID() { }
public DeviceShortMacID(IDeviceID id)
{
if (id is DeviceshortMacID)
this._ID = id.GetID();
else
this._ID = this.ConvertFrom(id);
}
public ID ConvertFrom(IDeviceID oldID) { ... convert code ...}
public ID GetID() { return this_ID; }
}
public interface IDeviceID
{
public ID GetID();
public ID ConvertFrom(IDeviceID oldID);
}
public class ID { } // I don't know what you return so I'm making up this class

OOP principles in C#

I have a library (no source), to an certain object of which, I need to add some properties.
What would be the a way to do it ? I'm aware I could extend the class and add properties to the child. As well I know there are NO Extension Properties in C# yet. What would you suggest ? Thank you !
The metadata of class could be something like :
public class ResultClass
{
public IList<Item> Results { get; set; }
public int TotalResults { get; set; }
}
and I want to add a :
String description;
to it. Thanks.
There are a couple strategies you could take. Inheritance is the most obvious one. You might also consider composition. Can you give us some more details about what the object is and what properties you need to add to it and why?
After seeing the expanded question:
Either strategy outlined above (composition or inheritance) will probably work for you. Personally, I prefer composition. I think it better insulates you from changes that might be made to the third party library. It also forces you to work through the public interface of the library class, which is preferable when you have no knowledge or control of the internals of a class.
Here is the most basic example of composition.
public CompositeClass
{
private ResultClass _resultClass = new ResultClass();
public IList<Item> Results
{
get { return _resultClass.Results; }
set { _resultClass.Results = value; }
}
public int TotalResults
{
get { return _resultClass.TotalResults; }
set { _resultClass.TotalResults = value; }
}
//
// New Property
//
public string Description { get; set; }
}
Why do you need to add properties? If this is for binding purposes then I would suggest creating a wrapper class or creating your own inherited type that can raise PropertyChanged events in response to various state changes in your third party types. Instead of telling us your proposed solution you should tell us the actual problem you are trying to solve. Also (as I can't vote to close/migrate), this is not really a valid discussion for this site.
I think you are mixing up Extension Methods with Extension Properties.
And the last ones do not exist in C#.
So you should extend the class or create an inheriting class.

Categories