I've got a large QueryModel class that overall looks like this:
public class QueryModel: IQueryModel
{
public int Property1 { get; set; }
... ~100 more fields like this
}
public interface IQueryModel
{
public int Property1 { get; set; }
... ~100 more fields like this
}
The IQueryModel is passed around when our API is processing a request. In our (very large) codebase, most code is effectful, so the model is both read and mutated freely.
I'm slowly separating pure and effectful code (in relation to this model) by introducing an immutable interface, to be passed to pure code only, like this:
// unchanged
public class QueryModel: IQueryModel
{
public int Property1 { get; set; }
... ~100 more fields like this
}
public interface IQueryModel : IQueryModelImmutable
{
public int Property1 { get; set; } // still implements both getters and setters
... ~100 more fields like this
}
public interface IQueryModelImmutable
{
public int Property1 { get; } // only has getters
... ~100 more fields like this
}
But now in each unit test, when mocking IQueryModel, I need to duplicate all set-ups like this:
Mock<IQueryModel> _queryModelMock = new(); // existing setup
_queryModelMock.Setup(m => m.Property1).Returns(100); // existing setup
_queryModelMock.As<IQueryModelImmutable>.Setup(m => m.Property1).Returns(100); // new setup
The production code is working fine, as the interface properties are simply inherited and resolved in the class, however Moq seems to require that the exact interface (and not its descendant) was mocked.
Is there any way to simplify these mock definitions, by e.g. enabling mock inheritance in some way?
EDIT: to explain why I need to use/mock both interfaces, here's a relevant piece of code under test:
// 1k LoC
public async Task LongStatefulMethod(IQueryModel model)
{
...
CallAnEffecfulMethod(model); // model mutated
...
// ComputeScorePure accepts the base interface - IQueryModelImmutable - as an argument
var computedScore = ComputeScorePure(model); // model not mutated
...
CallAnotherEffectfulMethod(model); // model mutated
...
}
You can workaround using Mock.Of<> or Mock.SetupAllProperties and setting the property manually:
// Mock<IQueryModel> mock = new ();
// mock.SetupAllProperties();
// var inherited = mock.Object;
var inherited = Mock.Of<IQueryModel>();
inherited.Property1 = 100;
IQueryModelImmutable #base = inherited;
Assert.AreEqual(100, inherited.Property1);
Assert.AreEqual(100, #base.Property1);
Related
I have two objects, lets call them A and B.
Each contain the following property:
[IgnoreDataMember]
public string SalesforceId { get; set; }
Then I have another two objects, lets call them UpdatedA and UpdatedB, which respectively extend A and B, and include nothing but:
[DataMember(Name = "sf__Id")]
public new string SalesforceId { get; set; }
[DataMember(Name = "sf__Created")]
public bool SalesforceCreated { get; set; }
The reason for this is so that I can use ServiceStack to convert A and B to CSV files and then use it again to convert CSV files from Salesforce back to C# Objects (If I don't ignore SalesforceId, the upload to Salesforce Bulk API 2.0 will fail).
So, the first question part of this question is do I really need to create two separate classes for UpdatedA and UpdatedB, as these classes are nearly identical and are actually both poltergeists, because I only use them in the following two methods:
private Dictionary<string, A> Update(Dictionary<string, A> aByExternalIds, RelayerContext context) {
IConfiguration config = context.Config;
string url = $"{config["SalesforceInstanceBaseUrl"]}/services/data/{config["SalesforceVersion"]}/jobs/ingest/{context.job.Id}/successfulResults";
this.restClient.Get(url, context.token)
.FromCsv<List<UploadedA>>()
.ForEach((updatedA) => {
if (aByExternalIds.TryGetValue(updatedA.ExternalId, out A oldA)) {
oldA.SalesforceId = updatedA.SalesforceId;
}
});
return aByExternalIds;
}
private Dictionary<string, B> Update(Dictionary<string, B> bBySalesforceAId, RelayerContext context) {
IConfiguration config = context.Config;
string url = $"{config["SalesforceInstanceBaseUrl"]}/services/data/{config["SalesforceVersion"]}/jobs/ingest/{context.job.Id}/successfulResults";
this.restClient.Get(url, context.token)
.FromCsv<List<UploadedB>>()
.ForEach((updatedB) => {
if (bBySalesforceAId.TryGetValue(updatedB.A__c, out B oldB)) {
oldB.SalesforceId = updatedB.SalesforceId;
}
});
return bBySalesforceAId;
}
Which leads to the second part of this question.
Both of these questions are very similar. We can see that the inputs are mapped by different properties on A and B... so I think I could do something like create an interface:
public interface Identifiable {
public string getIdentifier();
}
which would could be used to return either updatedA.ExternalId or updatedB.A__c.
But I'm not sure what the method signature would look like if I'm using generics.
Also, if I don't know how I could handle FromCsv<List<UploadedA>>() and FromCsv<List<UploadedB>>() in a generic way (maybe passing in a function?)
Anyway, to sum up, what I'd like to do is reduce those these two methods to just one, and if I can remove one or both of those Uploaded classes, so much the better.
Any ideas?
How about something like this:
public interface IBase
{
string SalesforceId { get; set; }
}
public class A : IBase
{
public string SalesforceId { get; set; }
}
public class UploadedA : A
{
public new string SalesforceId {
get => base.SalesforceId;
set => base.SalesforceId = value; }
public bool SalesforceCreated { get; set; }
}
public static void Update<T, TU>(Dictionary<string, T> oldBySalesForceId, Func<TU, string> updatedId)
where TU : T
where T : IBase
{
// Call service and read csv to produce a list of uploaded objects...
// Substituting with an empty list in the example
var list = new List<TU>();
foreach (var updated in list)
{
if (oldBySalesForceId.TryGetValue(updatedId(updated), out var old))
{
old.SalesforceId = updated.SalesforceId;
}
}
}
I have removed some details that did not seem relevant for the example. This uses generics with constraints and a interface to ensure both the updated and old value has a SalesForceId.
I changed the derived class so that it uses the same SalesforceId as the base class, you could change it to virtual/override if you prefer, but it is probably not a good idea that the base and derived class both have independent properties with the same name since it will be confusing.
It uses a delegate to describe the id/key for UpdatedA/UpdatedB. You could use an interface instead if you prefer.
I have a pub/sub queue that returns what I'll call QueueMessages.
A QueueMessage has a Type and a Body. The type is always a string but the body varies depending on the type. I want the inheriting class to set the message type. I want to add my own local properties for storing on processing datatables.
I was hoping to be able to define a generic object for the body and override in the inheriting classes but it fails as I'm changing the return type.
Interface:
interface IBaseQueueMessage
{
Guid Id { get; set; }
string MessageType { get; }
object Message { get; set; }
DateTime ConsumeDate { get; set; }
}
Base class:
public abstract class BaseQueueMessage:IBaseQueueMessage
{
public Guid Id { get; set; }
public abstract string MessageType { get; }
public abstract object Message { get; set; }
public DateTime ConsumeDate => DateTime.Now;
}
Inheriting Classes (there are 7 or 8 different ones in total)
public sealed class Type1Message: BaseCallType
{
public override string MessageType => "Type1Message";
public override Type1Message Message { get; set; }
}
public class Type1Message
{
public string aaa { get; set; }
public int bbb { get; set; }
}
public sealed class Type2Message: BaseCallType
{
public override string MessageType => "Type2Message";
public override Type2Message Message { get; set; }
}
public class Type2Message
{
public string aaa { get; set; }
public string bbb { get; set; }
public int ccc {get; set;}
public bool ddd {get; set;}
}
The above fails as I'm trying to return a specific class instead of the generic object. I understand why it would fail, but I'd like to know what would be the correct way of doing this please? I could just define individual classes for each and to hell with the interface and inheritance but it feels wrong to approach it that way. I intend to map the QueueMessage directly onto the inheriting classes for each different type so I want the model to match exactly what I pick up from the queue.
Apologies in advance for probably missing something really obvious, it's been a while since I did any coding and this is a relatively new area to me.
Edited to add more details on implementation problem
Lots of this works, thanks. Where I still have a problem is in the MessageHandlerWrapper. If I debug, then the handler object from the constructor that the method tries to use in _handler = handler is always null.
In my .net core startup.cs I have:
void RegisterHandler<TMessageType, THandler>()
where TMessageType : class
where THandler : IMessageHandler<TMessageType>
{
serviceCollection.AddSingleton<TMessageType>();
serviceCollection.AddSingleton(
serviceProvider => new MessageHandlerWrapper<TMessageType>(serviceProvider.GetService<THandler>(), serviceProvider)
);
}
...and it's the ...=> new MessageHandlerWrapper<... near the end of that block that is resolved by the dependency when I'm debugging in the code mentioned above, so I can't see why the service isn't available at that point.
Is there some way I can manually try to debug this by resolving the service to a concrete handler in MessageHandlerWrapper to see where the problem may lie?
For completeness, the whole section in startup.cs is:
//set up message handlers
var msgFactory = new MessageHandlerFactory();
//create local function to make it easier to add service references
void RegisterHandler<TMessageType, THandler>()
where TMessageType : class
where THandler : IMessageHandler<TMessageType>
{
serviceCollection.AddSingleton<TMessageType>();
serviceCollection.AddSingleton(
serviceProvider => new MessageHandlerWrapper<TMessageType>(serviceProvider.GetService<THandler>(), serviceProvider)
);
}
// Type1MessageHandler, etc is the implementation of IMessageHandler<Type1>
RegisterHandler<Type1, Type1MessageHandler>();
RegisterHandler<Type2, Type2MessageHandler>();
RegisterHandler<Type3, Type3MessageHandler>();
RegisterHandler<Type4, Type4MessageHandler>();
// some string constants for message types would be better.
serviceCollection.AddSingleton<IMessageHandlerFactory>(serviceProvider =>
{
msgFactory.RegisterHandler("Type1",
serviceProvider.GetService<MessageHandlerWrapper<Type1>>);
msgFactory.RegisterHandler("Type2",
serviceProvider.GetService<MessageHandlerWrapper<Type2>>);
msgFactory.RegisterHandler("Type3",
serviceProvider.GetService<MessageHandlerWrapper<Type3>>);
msgFactory.RegisterHandler("Type4",
serviceProvider.GetService<MessageHandlerWrapper<Type4>>);
return msgFactory;
});
serviceCollection.AddSingleton<IMessageHandler, MessageRouter>();
Here's an approach. The intent of the design is to enable you to write type-safe generic message handler classes, but be able to call them when you're starting from a message of type object. Bridging from one to the other can be a pain, and I think it's at the heart of your question.
This doesn't use inheritance for the messages. (You mentioned you were open to not inheriting.) I don't think it would add any value in this scenario, although this could be adapted to use inheritance.
First, here's a generic Message<T> class. This doesn't replace your existing message class. It's just that in order to have a type-safe generic handler, you need a generic message.
public class Message<T>
{
public Message(T content, Guid id, string messageType, DateTime consumeDate)
{
Content = content;
Id = id;
MessageType = messageType;
ConsumeDate = consumeDate;
}
public T Content { get; }
public Guid Id { get; }
public string MessageType { get; }
public DateTime ConsumeDate { get; }
}
Next, here's an interface for a message handler. The implementation doesn't matter for this example. What matters is that whatever T is, you can write a class to handle it.
public interface IMessageHandler<T>
{
void HandleMessage(Message<T> message);
}
This next interface and class are intended to serve as a "bridge" from your non-generic message (which uses object) to your generic message handler:
public interface IMessageHandler
{
void HandleMessage(IQueueMessage message);
}
public class MessageHandlerWrapper<TMessage> : IMessageHandler
{
private readonly IMessageHandler<TMessage> _handler;
public MessageHandlerWrapper(IMessageHandler<TMessage> handler)
{
_handler = handler;
}
// This is the critical part - it gets us from object to TMessage.
public void HandleMessage(IQueueMessage message)
{
_handler.HandleMessage(
new Message<TMessage>(
(TMessage)message.Message,
message.Id,
message.MessageType,
message.ConsumeDate));
}
}
Then you'll need a factory that returns the correct IMessageHandler depending on the message type string:
public interface IMessageHandlerFactory
{
IMessageHandler GetHandler(string messageType);
}
Putting all of this together connects your non-generic message to your generic message handler:
public class MessageRouter : IMessageHandler
{
private readonly IMessageHandlerFactory _messageHandlerFactory;
public MessageRouter(IMessageHandlerFactory messageHandlerFactory)
{
_messageHandlerFactory = messageHandlerFactory;
}
public void HandleMessage(IQueueMessage message)
{
var handler = _messageHandlerFactory.GetHandler(message.MessageType);
handler.HandleMessage(message);
}
}
This class also implements IMessageHandler. It's going to take the message, without caring what the type is, use the factory to get a more specific handler, and route the message to that handler.
Now we need to implement the factory. Here's an implementation which will allow us to resolve handlers from an IServiceProvider without resorting to a service locator:
public class MessageHandlerFactory : IMessageHandlerFactory
{
private readonly Dictionary<string, Func<IMessageHandler>> _messageHandlers
= new Dictionary<string, Func<IMessageHandler>>(StringComparer.OrdinalIgnoreCase);
public void RegisterHandler(string messageType, Func<IMessageHandler> getHandlerFunction)
{
_messageHandlers[messageType] = getHandlerFunction;
}
public IMessageHandler GetHandler(string messageType)
{
if (_messageHandlers.ContainsKey(messageType))
return _messageHandlers[messageType]();
throw new InvalidOperationException($"No handler is registered for message type {messageType}.");
// Or you could return some default handler that does something else with
// unknown message types.
}
}
Now we can register implementations as follows:
public static class MessageHandlerServiceCollectionExtensions
{
public static IServiceCollection AddMessageHandlers(this IServiceCollection services)
{
void RegisterHandler<TMessageType, THandler>()
where TMessageType : class
where THandler : IMessageHandler<TMessageType>
{
services.AddSingleton<TMessageType>();
services.AddSingleton(
serviceProvider => new MessageHandlerWrapper<TMessageType>(serviceProvider.GetService<THandler>())
);
}
// MessageTypeOneHandler is the implementation of IMessageHandler<MessageTypeOne>
RegisterHandler<MessageTypeOne, MessageTypeOneHandler>();
RegisterHandler<MessageTypeTwo, MessageTypeTwoHandler>();
// some string constants for message types would be better.
services.AddSingleton<IMessageHandlerFactory>(serviceProvider =>
{
var factory = new MessageHandlerFactory();
factory.RegisterHandler("messagetypeone",
serviceProvider.GetService<MessageHandlerWrapper<MessageTypeOne>>);
factory.RegisterHandler("messagetypetwo",
serviceProvider.GetService<MessageHandlerWrapper<MessageTypeTwo>>);
return factory;
});
services.AddSingleton<IMessageHandler, MessageRouter>();
return services;
}
}
Having done all of this, does it seem a bit complex? It does to me, but I still consider it worth the effort. Why?
The message handlers are type safe instead of allowing object to propagate through the code. We're containing it like a disease. We can create simple, testable, single-responsibility classes that implement IMessageHandler<TMessage>.
Everything gets resolved from the container. That means the message handlers could all have their own unique dependencies, and that would be okay.
No reflection. It's not that reflection is evil, but once we go down that road it seems to get worse.
There is a clear path forward for the you or the next developer if you need to add handlers for more types. Even if they have no idea how to register the handlers and they don't do it, the exceptions will give them a clear path forward, showing them what they need to do. If it's registered it will get resolved. If it's not, the factory will throw an exception.
Finally, all of this is testable, even the factory. If the message types were an enum you could just run one test to ensure that there's a handler for every type.
[DataTestMethod]
[DataRow("MessageTypeOne")]
[DataRow("MessageTypeTwo")]
public void FactoryResolvesMessageHandlers(string messageType)
{
var services = new ServiceCollection();
services.AddMessageHandlers();
var provider = services.BuildServiceProvider();
var factory = provider.GetService<IMessageHandlerFactory>();
var handler = factory.GetHandler(messageType);
Assert.IsNotNull(handler);
}
I have the following builder/factory which abstracts a serializeable model from a class.
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
}
}
And I have a concrete implementation of IFooModel like so:
public interface IFooModel
{
string AbstractedData1 { get; }
string AbstractedData2 { get; }
int AbstractedData3 { get; }
}
public class ConcreteFooModel : IFooModel
{
public string AbstractedData1 { get; set; }
public string AbstractedData2 { get; set; }
public int AbstractedData3 { get; set; }
public bool ExtraData1 { get; set; }
}
Now arises the issue, I am struggling to find a way to not reference any concrete implementations in my builder/factory method, e.g.
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
var model = new ConcreteFooModel(someClass.data1, someClass.data1); // Aaargh
}
}
Something about this code is smelly to me, perhaps this is the only way, but I don't like the idea of being forced into referencing the concrete implementation to instantiate the data class, IFooModel.
This gets more complex if I now introduce another data holder interface into the IFooModel
public interface IFooModel
{
string AbstractedData1 { get; }
string AbstractedData2 { get; }
int AbstractedData3 { get; }
IBarData BarData { get; }
}
public interface IBarData
{
// some data in here
}
Forcing me then to create another concrete reference for the nested interface
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
IBarData barData = new ConcreteBarData();
IFooModel model = new ConcreteFooModel(someClass.data1, someClass.data1, barData);
}
}
Is there a better way to do this while still sticking to the SOLID principle and IoC?
What's important is to look at this from the perspective of the class that depends on IFooModel That's probably the first place where you want to prevent coupling.
You can accomplish that by injecting the factory into the class that needs it, like this:
public class NeedsFooFactory
{
private readonly IFooBarFactory _factory;
public NeedsFooFactory(IFooBarFactory fooBarFactory)
{
_factory = factory;
}
public void WhatEverThisClassDoes(IFoo foo)
{
var fooBar = _factory.Create(foo);
// Do something
}
}
Now the class that depends on the factory is decoupled from any implementation. You can substitute or mock another implementation of the factory that returns a different implementation of IFooModel.
Something to stop and think about at this point: Do you need an abstraction for ConcreteFooModel at all? If it's just a class that holds data then maybe you don't.
Getting back to the factory: Now that you can replace the factory with any implementation, this becomes less of a concern:
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
IBarData barData = new ConcreteBarData();
IFooModel model = new ConcreteFooModel(someClass.data1, someClass.data1, barData);
}
}
This implementation of the factory returns a specific concrete implementation of IFooModel. Is that bad? At some level classes are going to deal with concrete classes. In this case I think it's okay because this factory is doing what it's supposed to do. You don't have to worry that it's coupled to ConcreteFooModel. If you want a class that returns a different implementation you could create a different implementation of IFooBarFactory that returns a different implementation of IFooModel.
Again, this becomes even less of a concern if you question whether you need an abstraction for your foo model. Quite possibly the concrete class is all you need, and what matters is that you can have different implementations of the factory that populates it.
I'm using Automapper to copy interfaces to different implementations (for serialization, for view model, for database mapping, etc...).
My code is a lot more complex but I've isolated the problem in the following code snippet sample.
Considering the following code, do I miss something because the second assertion is failing:
[Test]
public void AutoMapperTest()
{
Mapper.CreateMap<IMyBaseInterface, MyClass>();
Mapper.CreateMap<IMyInterface, MyClass>();
IMyBaseInterface baseInstance = new MyBaseClass{ MyBaseProperty = "MyBase" };
var concrete = Mapper.Map<MyClass>(baseInstance);
concrete.MyClassProperty = "MyClass";
MyClass mapped = Mapper.Map<IMyInterface,MyClass>(concrete);
Assert.AreEqual(concrete.MyBaseProperty, mapped.MyBaseProperty);
Assert.AreEqual(concrete.MyClassProperty, mapped.MyClassProperty);
}
Expected: "MyClass"
But was: null
public class MyClass : MyBaseClass, IMyInterface
{
public string MyClassProperty { get; set; }
}
public interface IMyInterface : IMyBaseInterface
{
string MyClassProperty { get; }
}
public class MyBaseClass : IMyBaseInterface
{
public string MyBaseProperty { get; set; }
}
public interface IMyBaseInterface
{
string MyBaseProperty { get; }
}
Environment:
Automapper : 4.1.1.0 / .Net: 4.5 / VS 2013
Work around:
Add Mapper.CreateMap<MyClass, MyClass>();
I don't see the above as a real answer. Since it means that if I have several implementations, I have to create mappings for all combinations. And add another mapping if I write a new implementation, even if the whole time, they all implement the same interface.
If you are using inheritance and you want to combine this with Automapper you have to say Automapper that this class is base for these classes, and these classes are children of this class. I had the same problem and it started work only when I specified ALL my inheritance relationships
Its better to check this doc page about inheritance config
I have a situation where I have some DTO classes that should be implemented like:
public class City
{
public string Name { get; set; }
public State State { get; set; }
}
public class State
{
public string Name { get; set; }
}
The problem is, these are actually DTO classes for REST XML resources. And the City resource may include the State resource inline, or it may simply provide the resource ID (a URI). I am handling access to the DTO via the Repository pattern and would like it to be transparent to clients whether State is lazy loaded or not (like how NHibernate does with it's entity classes).
So my current plan is to use Castle DynamicProxy to create a proxy object when the REST Repository detects that the class isn't fully "hydrated" (i.e. not everything is inline). The proxy object will know how to lazy load attributes as needed.
To actually implement this, however, the only thing I've come up with is to have backing attributes for all relationships and put the Xml attributes on those. So the strategy looks like this:
[XmlType]
public class City
{
[XmlElement]
public string Name { get; set; }
[ToOneRestRelationship(BackingPropertyName = "StateBacking")]
public State State { get; set; }
[XmlElement(Name = "state")]
public ResourceBase StateBacking { get; set; }
}
[XmlType]
public class State
{
[XmlElement]
public string Name { get; set; }
}
Then the Repository object knows to set up the proxy object to either get the object from the StateBacking property and use that (inlined resource case) or do a REST request to lazily retrieve the State object (resource URI case, i.e. lazy) from the ID specified in the backing property.
Question
The issue is, this backing field is pretty ugly. What I would like is a way to have Castle generate a class that would have the backing property with the XmlElement attribute applied that I could pass to the XmlSerializer. Then my DTO classes could look more like the first example and wouldn't have to be aware that the actual serialising class has a backing property.
Is something like this possible with Castle or any other Proxy library?
After going an interesting and completely wrong way, i think it is indeed possible to create a backing field that won't be seen by clients. Since proxying works by inheriting from the proxied class, any property on the derived class won't be seen in the scope of the original class. So mixins are the way to go:
Given Foo
public class Foo
{
public virtual string Name { get; set; }
public virtual Bar bar { get; set; }
}
and Bar
public class Bar
{
public virtual string Name { get; set; }
}
We can declare an interface that will let us retrieve the backing field and an implementation
public interface IHasBarBackingField
{
Bar RetrieveBar();
}
public class HasBarBackingField : IHasBarBackingField
{
public HasBarBackingField()
{
// the constructor must contain ways to resolve the bar. Since
// the class is built while proxying you should have all the data
// available at this moment
}
public Bar RetrieveBar()
{
return new Bar(); // example, you could have a backing field somewhere in this class
}
}
Then you just have to mixin both classes when proxying:
var pg = new ProxyGenerator();
var hasBarBackingField = new HasBarBackingField();
var options = new ProxyGenerationOptions();
options.AddMixinInstance(hasBarBackingField);
var test = pg.CreateClassProxy<Foo>(options, new BarInterceptor());
and intercept the call interesting you in order to return the backing Bar
public class BarInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (invocation.Method.Name == "get_bar")
{
var hasBarBackingField = invocation.InvocationTarget as IHasBarBackingField;
invocation.ReturnValue = hasBarBackingField.RetrieveBar();
}
else
{
invocation.Proceed();
}
}
}
The HasBarBackingField class should be built to return either the direct object or retrieve the referenced REST object. Hope this helps
Based on what i've seen NSubstitute do i'd say it is possible, as long as your properties are virtual: http://nsubstitute.github.io/help/partial-subs/ .
Creating a City class with virtual property State that is then resolved at runtime using the substitution pattern should be feasable
public class City
{
public string Name { get; set; }
[StateId(10)]
public virtual State State { get; set; }
}
var sCity = Substitute.For<City>();
sCity.State.Returns((core) => {return null; // here you can access informations about the call});
Definitely doable, but it's terra incognita from here on!