I created following sample model:
internal sealed class Bike : IVehicle
{
public Bike(
Engine engineType,
WindowHue windowHue,
Vehicle transport,
ushort wheelsCount,
string name) =>
(EngineType, WindowHue, Transport, WheelsCount, Name) =
(engineType, windowHue, transport, wheelsCount, name);
public WindowHue WindowHue { get; }
public Engine EngineType { get; }
public Vehicle Transport { get; }
public ushort WheelsCount { get; }
public string Name { get; }
}
I'm currently writing unit tests for Bike validator and I would like to use AutoFixture to create instances of Bike class that have values that are considered valid and invalid. Is there a way to instruct AutoFixture how to create those types of instances and tell it to fetch valid or invalid one depending on unit test that is running? For example: in test case that checks whether valid instance of Bike class passes validation I would like AutoFixture to create a valid Bike instance.
I attempted to achieve this behavior by creation of custom specimen builders but it seems that the last one that is registered is used to create an actual instance of requested type. Other idea was to create builder class that would use AutoFixture to create valid and invalid instances [via "Create" method] and use it in test cases, but I think that is not a good idea, since it leads to creation of redundant code [builder class per tested model].
If above behavior is possible, then is there a way to create such instances by using [AutoData] attribute, so that I don't have to call AutoFixture in test case body?
Yes you can, however the complexity of your setup code will depend on the complexity of your domain.
You could declare a customization that would build your DTO models with valid data, then use it via a custom [AutoData] attribute, and inside the test customize some of the DTOs with invalid data using .Customize<T>() or .Build<T>().
Now if you want to provide your invalid DTOs from the test parameters you could try to implement a [Invalid] attribute, that would customize individual test parameters, then use [Frozen] to use the value in other generated models.
For the [Invalid] attribute you can implement either the CustomizeAttribute from the AutoFixture.NUnit3 package or the IParameterCustomizationSource from AutoFixture.
As you'll see the output of the customization attribute is an ICustomization meaning inside the attribute you'll likely have a dictionary that outputs a customization for an invalid entity depending on the parameter type.
NB: I would really advise you use the first approach since it makes it obvious in what way the input data is invalid and makes asserting the results easier.
I would probably leave automapper out of this and create a class that takes care of creating the different types (invalid or valid) of objects that tests need:
Enums.cs
public enum BikeType
{
Valid,
Invalid
}
BikeCreator.cs
public static class BikeCreator
{
private Bike CreateValidBike()
{
return new Bike() //make this object "valid"
}
private Bike CreateInvalidBike()
{
return new Bike(); //make this object "invalid"
}
public Bike CreateInstance(BikeType bikeType)
{
Bike bike = null;
switch (bikeType)
{
case BikeType.Valid:
user = CreateValidBike();
break;
case BikeType.Invalid:
user = CreateInvalidBike();
break;
};
return bike;
}
}
That allows me to call that class in the following way:
//arrange
var invalidBike = BikeCreator.CreateInstance(BikeType.Invalid);
var validBike = BikeCreator.CreateInstance(BikeType.Valid);
This could be a good boilerplate to refactor into something more fancy with interfaces and generics. Sometimes "premature optimization is the root of all evil"
Related
For the purposes of this question, a 'constant reference' is a reference to an object from which you cannot call methods that modify the object or modify it's properties.
I want something like this:
Const<User> user = provider.GetUser(); // Gets a constant reference to an "User" object
var name = user.GetName(); // Ok. Doesn't modify the object
user.SetName("New value"); // <- Error. Shouldn't be able to modify the object
Ideally, I would mark with a custom attribute (e.g. [Constant]) every method of a class that doesn't modify the instance, and only those methods can be called from the constant reference. Calls to other methods would result in an error, if possible, during compile time.
The idea is I can return a read-only reference to and be sure that it will not be modified by the client.
The technique you're referring to is called "const-correctness" which is a language feature of C++ and Swift, but not C#, unfortunately - however you're onto something by using a custom attribute because that way you can enforce it via a Roslyn extension - but that's a rabbit-hole.
Alternatively, there's a much simpler solution using interfaces: because C# (and I think the CLR too) does not support const-correctness (the closest we have is the readonly field modifier) the .NET base-class-library designers added "read-only interfaces" to common mutable types to allow a object (wheather mutable or immutable) to expose its functionality via an interface that only exposes immutable operations. Some examples include IReadOnlyList<T>, IReadOnlyCollection<T>, IReadOnlyDictionary<T> - while these are all enumerable types the technique is good for singular objects too.
This design has the advantage of working in any language that supports interfaces but not const-correctness.
For each type (class, struct, etc) in your project that needs to expose data without risk of being changed - or any immutable operations then create an immutable interface.
Modify your consuming code to use these interfaces instead of the concrete type.
Like so:
Supposing we have a mutable class User and a consuming service:
public class User
{
public String UserName { get; set; }
public Byte[] PasswordHash { get; set; }
public Byte[] PasswordSalt { get; set; }
public Boolean ValidatePassword(String inputPassword)
{
Hash[] inputHash = Crypto.GetHash( inputPassword, this.PasswordSalt );
return Crypto.CompareHashes( this.PasswordHash, inputHash );
}
public void ResetSalt()
{
this.PasswordSalt = Crypto.GetRandomBytes( 16 );
}
}
public static void DoReadOnlyStuffWithUser( User user )
{
...
}
public static void WriteStuffToUser( User user )
{
...
}
Then make an immutable interface:
public interface IReadOnlyUser
{
// Note that the interfaces' properties lack setters.
String UserName { get; }
IReadOnlyList<Byte> PasswordHash { get; }
IReadOnlyList<Byte> PasswordSalt { get; }
// ValidatePassword does not mutate state so it's exposed
Boolean ValidatePassword(String inputPassword);
// But ResetSalt is not exposed because it mutates instance state
}
Then modify your User class and consumers:
public class User : IReadOnlyUser
{
// (same as before, except need to expose IReadOnlyList<Byte> versions of array properties:
IReadOnlyList<Byte> IReadOnlyUser.PasswordHash => this.PasswordHash;
IReadOnlyList<Byte> IReadOnlyUser.PasswordSalt => this.PasswordSalt;
}
public static void DoReadOnlyStuffWithUser( IReadOnlyUser user )
{
...
}
// This method still uses `User` instead of `IReadOnlyUser` because it mutates the instance.
public static void WriteStuffToUser( User user )
{
...
}
So, these are the first two ideas I initially had, but don't quite solve the problem.
Using Dynamic Objects:
The first idea I had was creating a Dynamic Object that would intercept all member invokations and throw an error if the method being called isn't marked with a [Constant] custom attribute. This approach is problematic because a) We don't have the support of the compiler to check for errors in the code (i.e. method name typos) when dealing with dynamic objects, which might lead to a lot of runtime errors; and b) I intend to use this a lot, and searching for method names by name every time a method is called might have considerable performance impact.
Using RealProxy:
My second idea was using a RealProxy to wrap the real object and validate the methods being called, but this only works with objects that inherit from MarshalByRefObject.
In this example for the NYPizzaIngredientFactory, they can only make pizza with ThinCrustDough. How can i make a pizza that could use another factory's ingredients like ThickCrustDough from ChicagoPizzaIngredientFactory. I want to try stay away from builder and stick with abstract factory patterns and factory methods.
Your NYPizzaStore would have to use the ChicagoPizzaIngredientFactory if you want it to be able to use ThickCrustDough.
If you think about the practicality of this, however, it probably doesn't make sense to have them ship you the ingredients from Chicago.
In my mind, you have two options:
Have another factory located in NY that can produce thick dough (e.g. NYThickPizzaIngredientFactory). This is because your interface has a single createDough method that takes no arguments so you can't tell it what type of dough to make. It can only make one.
Alter your interface so that the createDough method accepts arguments that can tell the factory what type of dough to create. This is the one I would recommend.
The type of arguments can also be based on the particular factory. For instance:
//TDoughArts tells you what type of arguments the factory needs in order to make dough.
public interface IPizzaIngredientFactory<TDoughArgs> where TDoughArgs : IDoughArgs
{
//....
IDough CreateDough(TDoughArgs doughArgs);
//....
}
public interface IDoughArgs
{
}
public class NYPizzaDoughArgs : IDoughArgs
{
public enum DoughTypes
{
Thin = 0,
Thick = 1
}
public DoughTypes DoughType { get; set; }
}
public class NYPizzaIngredientFactory : IPizzaIngredientFactory<NYPizzaDoughArgs>
{
//....
public IDough CreateDough(NYPizzaDoughArgs doughArgs)
{
//Make the right dough based on args here
if(doughArgs.DoughType == DoughTypes.Thin)
//...
}
//....
}
I whipped this out in a few minutes so check for consistency, but I think you will get the idea.
You don't have to use generics. You can simply stick with the IDoughArgs interface if you don't want more specificity.
Usage:
var factory = new NYPizzaIngredientFactory();
var args = new NYPizzaDoughArgs();
args.DoughType = NYPizzaDoughArgs.DoughTypes.Thick;
var dough = factory.createDough(args);
The first problem I see is this:
public interface IDoughArgs
{
}
public class NYPizzaDoughArgs : IDoughArgs
{
public enum DoughTypes
{
Thin = 0,
Thick = 1
}
public DoughTypes DoughType { get; set; }
}
IDoughArgs has no members. The class that implements it, NYPizzaDoughArgs, has properties which are not implementations of IDoughArgs. That renders the IDoughArgs interface meaningless.
Additionally, look at this class declaration:
public class NYPizzaIngredientFactory : IPizzaIngredientFactory<NYPizzaDoughArgs>
What class is going to "know" the generic argument and know to create this class as opposed to some other generic implementation? It's going to get confusing when you get to that part. You'll need some sort of factory to create your factory.
Then, if you decide that ingredient factories vary by more than just the type of dough, and you need more generic arguments, it's going to get really messy.
And, what happens if, in addition to having options such as thickness that are specific to just one dough type, you need options that are specific to just one thickness? Perhaps thick dough is only an option if you've selected New York or Chicago style (not European) and stuffed crust is only an option if you've selected a thick crust. That's going to get really difficult to describe with interfaces. It sounds more like data.
Here's a stab at another way to implement this:
public enum PizzaStyle
{
NewYork = 1,
Chicago = 2,
Greek = 4
}
public enum CrustType
{
Thick = 1024,
Thin = 2048,
HandTossed = 4096
}
public enum CrustOption
{
Stuffed = 32768
}
public enum PizzaDoughOption
{
NewYorkThin = PizzaStyle.NewYork + CrustType.Thin,
NewYorkHandTossed = PizzaStyle.NewYork + CrustType.HandTossed,
NewYorkThick = PizzaStyle.NewYork + CrustType.Thick,
NewYorkThickStuffed = NewYorkThick + CrustOption.Stuffed,
ChicagoThin = PizzaStyle.Chicago + CrustType.Thin,
ChicagoHandTossed = PizzaStyle.Chicago + CrustType.HandTossed,
ChicagoThick = PizzaStyle.Chicago + CrustType.Thick,
ChicagoThickStuffed = ChicagoThick + CrustOption.Stuffed,
Greek = PizzaStyle.Greek // only comes one way?
}
There are other ways to represent this same data. Even if there were fifty values in the PizzaDoughOption enumeration, it's probably still easier that way, building a definitive, readable list of valid options, as opposed to trying to represent that in code with a bunch of branches. (If you want to unit test that, you'll end up coding every single combination anyway in unit tests.)
And there are several ways you could use this data. You could present just a big list of options. You could allow users to select from the various options and, as you go, determine whether it matches a valid combination. Or they could select any option and you could narrow the list of options according to which include the desired option. (You want a stuffed crust? Ok, that's either New York thick crust or Chicago thick crust.)
Now, if you need a factory to create dough according to type, you could do this:
public interface IDoughFactory
{
Dough GetDough(PizzaDoughOption doughOption);
}
The implementation might look something like this. To be honest I might use a "factory factory" here, but for now since there are only three types I'll keep it simpler.
public class DoughFactory : IDoughFactory
{
// Each of these also implement IDoughFactory
private readonly NewYorkDoughFactory _newYorkDoughFactory;
private readonly ChicagoDoughFactory _chicagoDoughFactory;
private readonly GreekDoughFactory _greekDoughFactory;
public DoughFactory(
NewYorkDoughFactory newYorkDoughFactory,
ChicagoDoughFactory chicagoDoughFactory,
GreekDoughFactory greekDoughFactory)
{
_newYorkDoughFactory = newYorkDoughFactory;
_chicagoDoughFactory = chicagoDoughFactory;
_greekDoughFactory = greekDoughFactory;
}
public Dough GetDough(PizzaDoughOption doughOption)
{
if (MatchesPizzaStyle(doughOption, PizzaStyle.NewYork))
return _newYorkDoughFactory.GetDough(doughOption);
if (MatchesPizzaStyle(doughOption, PizzaStyle.Chicago))
return _chicagoDoughFactory.GetDough(doughOption);
if (MatchesPizzaStyle(doughOption, PizzaStyle.Greek))
return _greekDoughFactory.GetDough(doughOption);
// Throw an exception or return a default dough type. I'd throw the exception.
}
private bool MatchesPizzaStyle(PizzaDoughOption doughOption, PizzaStyle pizzaStyle)
{
return ((int) doughOptions & (int) pizzaStyle) == (int) pizzaStyle;
}
}
Now your more concrete dough factories (New York, Chicago, Greek) all receive the same PizzaDoughOption. If they care whether thin or thick has been selected, they can handle it. If that option doesn't exist they can ignore it. Even if something has gone wrong in an outer class and somehow someone has invoked GreekDoughFactory with the StuffedCrust option, it won't fail. It just ignores it.
What would be the possible point to all of this?
First, the class creating a pizza has no knowledge of the intricacies of creating the right dough type. It just depends on a dough factory, passes a parameter, and gets the right dough. That's simple and testable.
Second, you don't have to call new anywhere. You can employ dependency injection all the way down. That way the class that depends on the abstract IDoughFactory doesn't know anything about what dependencies DoughFactory has.
Likewise, maybe the concrete dough factories have dependencies of their own and they differ significantly from one to the next. As long as those are getting resolved from the container and injected into DoughFactory, that's fine, and DoughFactory won't know anything about their dependencies.
All of the dependencies are wired up in your DI container, but the classes themselves are small, simple, and testable, depending on abstractions and not coupled to implementations of anything.
Someone might look and this and think it's a little more complicated. What's critical is that not only does it keep individual classes decoupled, but it leaves a path forward for future change. The design of your classes, which shouldn't have to change too much, won't closely mirror the details of specific types of pizzas, which can and should change. You don't want to have to re-architect your pizza application because of a new kind of pizza.
I'm using Redis Cache using Stack Exchange library.
I used cloudStructure library to use Redis Dictionary and Redis List.
Problem is when I try to retrieve values and if that model has a null
value for one list property it is throwing me below exception -
Jil.DeserializationException : Error occurred building a deserializer
for TestMainClass: Expected a
parameterless constructor for
System.Collections.Generic.ICollection1[TestChildClass]
---- Jil.Common.ConstructionException : Expected a parameterless constructor for
System.Collections.Generic.ICollection1[TestChildClass]
public class TestMainClass
{
public TestMainClass();
public int Id { get; set; }
public virtual ICollection<TestChildClass> Mydata { get; set; }
public string Title { get; set; }
}
public class TestChildClass
{
public TestChildClass();
public int Id { get; set; }
public string Value { get; set; }
}
Redis code for retrieve value:
RedisDictionary<int, TestMainClass> dictionary =
new RedisDictionary<int, TestMainClass>("localhost", "mylocaldictionary");
var result = await dictionary.Get(121);
What If I could not able to convert ICollection < T > into List < T >?
It might be a nice feature if the serialization library detected interfaces like ICollection<T> and IList<T> and implemented them with the concrete List<T> during deserialization, but ultimately: every feature needs to be thought of, considered (impact), designed, implemented, tested, documented and supported. It may be that the library author feels this is a great idea and should be implemented; it might not be high on the author's list, but they'd be more than happy to take a pull request; or there might be good reasons not to implement it.
In the interim, as a general rule that will solve virtually every serialization problem you will ever encounter with any library:
the moment the library doesn't work perfectly with your domain model: stop serializing your domain model - use a DTO instead
By which, I mean: create a separate class or classes that are designed with the specific choice of serializer in mind. If it wants List<T>: then use List<T>. If it wants public fields: use public fields. If it wants the types to be marked [Serializable]: mark the types [Serializable]. If it wants all type names to start with SuperMagic: then start the type name with SuperMagic. As soon as you divorce the domain model from the serialization model, all the problems go away. In addition: you can support multiple serializers in parallel, without getting into the scenario that A needs X and doesn't work with Y; B needs Y and doesn't work with X.
All you then need to do is write a few lines of code to map between the two similar models (or use libraries that do exactly that, like AutoMapper).
We have an existing WCF service which uses several DataContracts. We want to modify the serialization based on the device, so that when accessed from mobile devices, the service should serialize only some important data members(not all)
We have 2 options here
Create separate operation and data contracts for different types of
devices
Mess with the actual xml serialization and suppress creating
unnecessary elements based on the device
We don't want to go with the first option since it introduces a lot of redundant code problems in the future
Small research showed that we need to use IXmlSerializable and override the readXML() and writeXML() methods. But at the same time, I have seen somewhere that DataContract and IXmlSerializable should not be used together
Any example to mess with actual serialization is greatly appreciated .
[DataContract]
public class TokenMessage
{
string tokenValue;
string extraValue;
[DataMember]
public string Token
{
get { return tokenValue; }
set { tokenValue = value; }
}
[DataMember]
public string Extra
{
get { return extraValue; }
set { extraValue = value; }
}
}
Now when i access the service which returns a typical TokenMessage data contract, from a mobile device, i don't want the "Extra" data member to be serialized i.e. When I supply a different argument to the operation contract, it should be able to serialize some/all the data members(depending on the action)
PS: For now please ignore the device detection part. Lets assume we have an argument in the operation contract, which helps us identify the device
I'm not convinced that some variant of #Pranav Singh's answer isn't a better design, but that's not your question...
As you mentioned in a comments attributes in .NET are static by design. This means dynamically adding/removing [DataMember] isn't a good option. It is possible. There are options like using Reflection.Emit to recreate the instance with the meta data changes (see all the answers to Can attributes be added dynamically in C#?) but all of those routes are complicated.
I see two reasonable options:
1) Implement an IParameterInspector for the service. In the AfterCall() method you could inspect and alter the parameters being returned to the client before they are serialized. There is some work to use reflection to dynamically determine the parameter types and set their values, but its not complicated. This is the better design that enables reuse of the behavior across many contracts or services. Carlos Figueira's blog is the best source for WCF extension examples.
2) Use the [OnSerializing] and [OnSerialized] events. In the [DataContract] you could temporarily alter what the properties are returning during serialization. The events are actually designed to enable initialization and as such this solution is a bit of a hack. This solution is also not thread safe. But it does keep the code contained to the DataContract class and solves the problem quickly (and I think you are looking for quick).
Solution #2 mights look something like:
[DataContract]
public class TokenMessage
{
string tokenValue;
string extraValue;
bool enableExtraValue = true;
[DataMember]
public string Extra
{
get {
if (enableExtraValue)
return extraValue;
return null;
}
set { extraValue = value; }
}
[OnSerializing()]
internal void OnSerializingMethod(StreamingContext context)
{
enableExtraValue = false;
}
[OnSerialized()]
internal void OnSerializedMethod(StreamingContext context)
{
enableExtraValue = true;
}
}
Solution #2 is a quick fix (which is what I think you are looking for).
Solution #1 is the better design.
Try using IgnoreDataMemberAttribute
There is a approach, but I think this will require extra DataContract to be generated but still no need for separate operation and data contracts for different types of devices.
It can classic implementation to run-time polymorphism. I am just giving idea:
Say you have a generic DataContract like :
[DataContract]
[KnownType(typeof(Extra))]
[KnownType(typeof(Extra2))]
public class TokenMessage
{
string tokenValue;
string extraValue;
[DataMember]
public string Token
{
get { return tokenValue; }
set { tokenValue = value; }
}
}
Other device specific contracts can inherit TokenMessage as base class like:
[DataContract]
public class Extra:TokenMessage
{
[DataMember]
public string Extra
{
get ;set;
}
}
[DataContract]
public class Extra2:TokenMessage
{
[DataMember]
public string Extra2
{
get ;set;
}
}
Now at run-time as you say you know an argument in the operation contract, which helps us identify the device. Say based on device type, you can instantiate base class with derived class like:
TokenMessage tm= new Extra();
OR
TokenMessage tm= new Extra2();
So at run-time you will decide which device contract will be part of genric response.
Note: Adding KnownType will generate the separate xsd within wsdl for all known types within base class, but saves serialization for data at run-time as this should depend on actual inheritance chosen.
In your model add a property 'ShouldSerializeYOUR_PROPERTY_NAME', set it to false when you do not want the property serialized.
See more here: http://msdn.microsoft.com/en-us/library/system.windows.dependencyobject.shouldserializeproperty(v=vs.110).aspx
I want to add metadata to my object graph for non-domain type data that will be associated to my objects but is not essential to the problem set of that domain. For example, I need to store sort settings for my objects so that the order in which they appear in the UI is configurable by the user. The sort indices should be serializable so that the objects remember their positions. That's just one among a few other metadata items I need to persist for my objects. My first thought is to solve this by having a MetadataItem and a MetadataItemCollection where the base Entity class will have a "Meta" property of type MetadataItemCollection. E.g.:
public class MetadataItem
{
public string Name;
public object Data;
}
public class MetadataItemCollection
{
/* All normal collection operations here. */
// Implementation-specific interesting ones ...
public object Get(string name);
public MetadataItem GetItem(string name);
// Strongly-type getters ...
public bool GetAsBool(string name);
public string GetAsString(string name);
// ... or could be typed via generics ...
public T Get<T>(string name);
}
public class Entity
{
public MetadataItemCollection Meta { get; }
}
A few concerns I can think of are:
Serialization - the database has a single table of EntityID | Name | Value where Value is a string and all types are serialized to a string?
Future Proofing - what if a metadata item's type (unlikely) or name needs to be changed?
Refactorability - should the keys come from a static list via enum or a class with static string properties, or should free-form strings be allowed:
var i = entity.Meta["SortIndex"];
vs.
public enum Metadatas { SortIndex };
var i = entity.Meta[Metadatas.SortIndex];
vs.
public static class Metadatas
{
public static string SortIndex = "SortIndex";
}
var i = entity.Meta[Metadatas.SortIndex];
Anything else?
Thoughts, ideas, gotchas???
Thanks for your time.
Solution:
Following #Mark's lead, and after watching the Udi video Mark linked to, I created two new interfaces: IUiPresentation and IUiPresentationDataPersistor. It's important to note that none of the objects in my Entity object model have any awareness of these interfaces; the interfaces are in a separate assembly and never referenced by my Entity object model. The magic is then done via IoC in the presentation models. It would be something like the following:
public class PhoneViewModel
{
IUiPresentationDataPersistor<Phone> _uiData
IUiPresentation<Phone> _presenter;
// Let IoC resolve the dependency via ctor injection.
public PhoneViewModel(Phone phone, IUiPresentationDataPersistor<Phone> uiData)
{
_uiData = uiData;
_presenter = uiData.Get(phone); // Does a simple lookup on the phone's ID.
}
public int SortIndex
{
get { return _presenter.SortIndex; }
set { _presenter.SortIndex = value; }
}
public void Save()
{
_uiData.Save();
}
}
It's a little more complicated in that the ViewModel implements INotifyPropertyChanged to get all the goodness that it provides, but this should convey the general idea.
Metadata literally means data about data, but what you seem to be asking for is a way to control and change behavior of your objects.
I think such a concern is much better addressed with a Role Interface - see e.g. Udi Dahan's talk about Making Roles Explicit. More specifically, the Strategy design pattern is used to define loosely coupled behavior. I'd look for a way to combine those two concepts.
As we already know from .NET, the use of static, weakly typed attributes severely limits our options for recomposing components, so I wouldn't go in that direction.