Call multiple classes with the same interface - c#

I have an interface like
public interface IAddressProvider
{
string GetAddress(double lat, double long);
}
In my consuming class I want to cycle through the concrete providers until I get a result, like (simplified):
string address;
address = _cachedAddressProvider.GetAddress(lat, long);
if(address == null)
address = _localDbAddressProvider.GetAddress(lat, long);
if(address = null)
address = _externalAddressProvider.GetAddress(lat, long);
return address ?? "no address found";
I can then mock each provider for unit testing, setting null as the return value to appropriately test all code paths.
How would i inject the interface into my consuming class (preferably using StructureMap) so that each concrete implementation is correctly resolved?

The fact that you have multiple address-providers is not something the calling code should have to deal with. So create a specific provider-proxy to handle with these multiple providers.
Like this.
public interface IAddressProvider {
string GetAddress(double lat, double long);
}
public class AddressProviderProxy: IAddressProvider {
public AddressProviderProxy(IAddressProvider[] providers) {
_providers = providers; // TODO: Add a NULL guard
}
private readonly IAddressProvider[] _providers;
string IAddressProvider.GetAddress(double lat, double long) {
foreach (var provider in _providers) {
string address = provider.GetAddress(lat, long);
if (address != null)
return address;
}
return null;
}
}
// Wire up using DI
container.Register<IAddressProvider>(
() => new AddressProviderProxy(
new IAddressProvider[3] {
cachedAddressProvider,
localDbAddressProvider,
externalAddressProvider
}
)
);
// Use it
IAddressProvider provider = ...from the container, injected..
string address = provider.GetAddress(lat, long) ?? "no address found";

Could you not just use container.GetAllInstances?, like so:
var address = new List<string>();
foreach (var provider in container.GetAllInstances<IAddressProvider>())
{
address.add(provider.GetAddress(lat, long));
}
Edit:
I see what you mean now. If you're using StructureMap 2.x then I would recommend looking at the Conditionally clause. However this has been removed in version 3 in favour of creating your own builder class that should be responsible for returning the correct instance.
For example:
public class AddressProviderBuilder : IInstanceBuilder
{
private readonly IContainer container;
public AddressProviderBuilder(IContainer container)
{
this.container = container;
}
public IAddressProvider Build()
{
foreach (var provider in this.container.GetAllInstances<IAddressProvider>())
{
if (provider.GetAddress(lat, long) != null)
{
return provider;
}
}
return null;
}
}

I'm not familiar with StructureMap specifically but there are two solutions as far as I can see.
1) Named Instances - You register your 3 concrete implementations of IAddressProvider with StructureMap as named instances, and then configure the constructor parameters.
StructureMap named instance configuration: http://docs.structuremap.net/InstanceExpression.htm#section14
Using named parameters in constructor injection: http://lookonmyworks.co.uk/2011/10/04/using-named-instances-as-constructor-arguments/
2) More Interfaces - Assuming that there's only ever going to be a few IAddressProvider implementations and not hundreds you could create an ICachedAddressProvider, ILocalDbAddressProvider, and IExternalAddressProvider that implement IAddressProvider and then use those in the constructor of the consuming class.
If there are likely to be significantly more concrete IAddressProvider implementations then you might want to look into something along the lines of an Abstract Factory instead.

Related

How to return a different object depending on IF in C# (Generics)

I have an ASP.NET MVC (Not Core) project where I have run into some problems, and I think finally getting around to learning how to properly use generics could be a solution to my problems.
My case is that I have a SQL connection, that returns data and depending on the result of one field in the SQL, I want to use two different models. The models have a lot of properties in common so I thought the best practice would be to create a method that selects which of the models to create, fill in the differences, return the model and then continue to fill in the "common" properties.
I have tried to read a little on Generics but I am quite new to this so I haven't made any big strides.
My code example looks like this:
public ResultVM MainClass()
{
var resultData = new ResultVM();
// ... SQL returns data
while (reader.Read())
{
resultData.Add(reader);
}
return resultData;
}
public object CreateObject(SqlDataReader indata)
{
if((indata["Associate"].ToString()) == "0")
{
var individual = new Individual();
}
else
{
var group = new Group();
}
return object;
}
How can I dynamically (depending on the value of Associate field) create an individual or a group?
I suggest working directly with System.Type in your case. Here can be multiple more elegant solutions of your problem, depending of what you actually need:
indata.GetFieldType(int ordinal) will return the .NET type of your field
Serialize data with type handling, then you can simply get type after non generic deserialization. For example:
var result = JsonConvert.DeserializeObject(dataJson);
result will have Type of your actual object type. You can check it writing result.GetType() and create an object of this type. For more advanced use see Activator.CreateInstance(...)
For the most cases using interface is the best way:
interface ISomething
{
// ...
}
class Individual : ISomething
{
// ...
}
class Group : ISomething
{
// ...
}
Then you cat build your non generic method this way:
public ISomething CreateObject(SqlDataReader indata)
{
if((indata["Associate"].ToString()) == "0")
return new Individual();
else
return new Group();
}
Your generic object creation may look something like this:
public T CreateObject<T>(SqlDataReader indata)
{
var o = new T();
return o;
}
Where T is type, that you pass outside this method: CreateObject<YourType>(indata)
T can be any Type you want including Interfaces. Also working with generics you may want check types by using is keyword, but I recommend using interfaces and avoid is checks at all.
Example:
if(yourObject is YourType)
{
(yourObject as YourType).SomeSpecificToYourTypeMethod();
// ...
}
What about implementing an interface with all the common properties?
Something like
interface IInterface
{
string CommonProperty1 { get; set; }
string CommonProperty2 { get; set; }
}
class Individual : IInterface
{
// ...
}
class Group : IInterface
{
// ...
}
public IInterface CreateObject(SqlDataReader indata)
{
if((indata["Associate"].ToString()) == "0")
{
var individual = new Individual();
// ...
return individual;
}
else
{
var group = new Group();
// ...
return group;
}
}

Is this method returning a System.Object class an anti-pattern?

I work an an automation team designing tests for electronic components. One thing our framework sorely needs is a single source point for our driver objects for the various pieces of test equipment at a workbench (right now, driver object creation is very wild-west).
Basically, the idea would be there would be one object, constructed based on a configuration file(s), which is the single place all other test code looks to to get the driver objects, based on a name string. I'll call it a "DriverSource" here.
The problem is, these drivers do not present similar interfaces at all. One might be a power supply (with methods like "SetVoltage" and "SetCurrentLimit"), while another might be a digital multimeter (with methods like "ReadVoltage" or "ReadCurrent").
The best solution I've come up with is to have a method with the following declaration:
public object GetDriver(string name);
Then, the test code using my "DriverSource" object would call that method, and then cast the System.Object to the correct driver type (or more accurately, the correct driver interface, like IPowerSupply).
I think casting like that is acceptable because whatever test code is about to use this driver had better know what the interface is. But I was hoping to get some input on whether or not this is an anti-pattern waiting to bite me. Any better pattern for solving this issue would also be greatly appreciated.
A final note: I think this is obvious, but performance is essentially a non-issue for this problem. Fetching the drivers is something will happen less than 100 times in a test run that can last hours.
If you already know the type and you're going to cast to an interface or class anyway, a better approach would be to hand the method call a type parameter.
public T GetDriver<T>(string name);
You can then use a Factory pattern to return you an object of the appropriate type from the method.
public T GetDriver<T>(string name)
{
switch(typeof(T).Name)
{
case "Foo":
// Construct and return a Foo object
case "Bar":
// Construct and return a Bar object
case "Baz":
// Construct and return a Baz object
default:
return default(T);
}
}
Usage:
var driver = GetDriver<Foo>(someString); // Returns a Foo object
If you really want to make this generic, I would use a factory pattern.
Lets start off by identifying the type structure:
public interface IDriver
{
}
public interface IPowerSupply : IDriver
{
void SetVoltage();
void SetCurrent();
}
public interface IMultimeter : IDriver
{
double MeasureVoltage();
}
Which you can add to or remove from as needed. Now we need a way for the factory to auto-discover the correct types and provide the configuration information to it. So lets create a custom attribute:
public class DriverHandlerAttribute : Attribute
{
public Type DriverType { get; set; }
public string ConfigurationName { get; set; }
}
And then we need a place to store configuration data. This type can contain whatever you want, like a dictionary of keys/values that are loaded from configuration files:
public class Configuration
{
public string DriverName { get; set; }
public string OtherSetting { get; set; }
}
Finally we can create a driver. Lets create an IPowerSupply:
[DriverHandler(DriverType = typeof(IPowerSupply), ConfigurationName="BaseSupply")]
public class BasePowerSupply : IPowerSupply
{
public BasePowerSupply(Configuration config) { /* ... */ }
public void SetVoltage() { /* ... */ }
public void SetCurrent() { /* ... */ }
}
The important part is that it is decorated with the attribute and that it has a constructor (although I created the factory so that it can use default constructors too):
public static class DriverFactory
{
public static IDriver Create(Configuration config)
{
Type driverType = GetTypeForDriver(config.DriverName);
if (driverType == null) return null;
if (driverType.GetConstructor(new[] { typeof(Configuration) }) != null)
return Activator.CreateInstance(driverType, config) as IDriver;
else
return Activator.CreateInstance(driverType) as IDriver;
}
public static T Create<T>(Configuration config) where T : IDriver
{
return (T)Create(config);
}
private static Type GetTypeForDriver(string driverName)
{
var type = (from t in Assembly.GetExecutingAssembly().GetTypes()
let attrib = t.GetCustomAttribute<DriverHandlerAttribute>()
where attrib != null && attrib.ConfigurationName == driverName
select t).FirstOrDefault();
return type;
}
}
So to use this, you would read in the configuration data (loaded from XML, read from a service, files, etc). You can then create the driver like:
var driver = DriverFactory.Create(configuration);
Or if you are using the generic method and you know the configuration is for a power supply, you can call:
var driver = DriverFactory.Create<IPowerSupply>(configuration);
And when you run your tests, you can verify that you get the right data back, for example, in your test method:
Assert.IsTrue(driver is IPowerSupply);
Assert.IsTrue(driver is BaseSupply);
Assert.DoesWhatever(((IPowerSupply)driver).SetVoltage());
And so-on and so-forth.
I would go with this code:
public T GetDriver<T>(string name)
{
return ((Func<string, T>)_factories[typeof(T)])(name);
}
The _factories object looks like this:
private Dictionary<Type, Delegate> _factories = new Dictionary<Type, Delegate>()
{
{ typeof(Foo), (Delegate)(Func<string, Foo>)(s => new Foo(s)) },
{ typeof(Bar), (Delegate)(Func<string, Bar>)(s => new Bar()) },
{ typeof(Baz), (Delegate)(Func<string, Baz>)(s => new Baz()) },
};
Basically the _factories dictionary contains all of the code to create each object type based on string parameter passed in. Note that in my example above the Foo class takes s as a constructor parameter.
The dictionary can also then be modified at run-time to suite your needs without needing to recompile code.
I would even go one step further. If you define this factory class:
public class Factory
{
private Dictionary<Type, Delegate> _factories = new Dictionary<Type, Delegate>();
public T Build<T>(string name)
{
return ((Func<string, T>)_factories[typeof(T)])(name);
}
public void Define<T>(Func<string, T> create)
{
_factories.Add(typeof(T), create);
}
}
You can then write this code:
var drivers = new Factory();
drivers.Define(s => new Foo(s));
drivers.Define(s => new Bar());
drivers.Define(s => new Baz());
var driver = drivers.Build<Foo>("foo");
I like that even better. It's strongly-typed and easily customized at run-time.

Possible bad practice in Web API ViewModel pattern?

I'm currently implementing ViewModels within my WebApi by injecting a Model object into the constructor of my 'ViewModelProduct' Object, as shown:
public class ViewModelProduct
{
private IProduct _product;
private int _ID;
private string _name;
public ViewModelProduct(IProduct product)
{
_product = product;
ID = _product.ID;
Name = _product.Name;
}
public int ID
{
set { _ID = _product.ID; }
get { return _ID; }
}
public string Name
{
set { _name = value; }
get { return _name;}
}
public string Description
{
set { _product.Description = value; }
get { return _product.Description; }
}
Within the Controller - in my case, the 'ProductController' I want to create an instance of the 'ViewModelProduct'. I want to reduce close coupling where ever possible.
I inject an 'IFacade' object into the constructor of my controller through the use of Unity from a BootStrapper class.
The real question here is I currently have a static method simply returning a new instance of the 'ViewModelProduct' object which I send the Model to to set within its constructor, as shown. Is this bad practice? I can't think how I could create an instance with Unity as I dont know what the model will be before runtime
public List<ViewModelProduct> GetProducts()
{
var V2Ops = _facade.GetOperatorV2();
var productList = V2Ops.GetProducts();
List<ViewModelProduct> listObjects = new List<ViewModelProduct>();
foreach (var product in productList)
{
//*****Setting a new instance from a static method.*****
var viewModel = CreateNewViewModelV2.CreateViewModel(product);
listObjects.Add(viewModel);
}
return listObjects;
}
Static Class returning a new 'ViewModelProduct' instance:
public static ViewModelProduct CreateViewModel(IProduct passedProductModel)
{
return new ViewModelProduct(passedProductModel);
}
It's not bad practice, I actually do it all the time but as an extension method (for IProduct). However, in this particular case, do you really need a factory method? Just doing a new ViewModelProduct(product) should be enough.
Your other option though is not quite good. It's a view model, a DTO for an IProduct, using a DI Container is way overkill and has no benefits. Btw, I don't think the viewmodel needs to be abstracted. As data structure it has no real behaviour (at most some helpers), it's not like you'll have multiple variations of it.
Another way I have gone about this, is as follows:
public static IViewModelProduct CreateViewModel(IProduct passedProductModel)
{
var viewModelContainer = new UnityContainer();
viewModelContainer.RegisterType<IViewModelProduct, ViewModelProduct>(new InjectionConstructor(passedProductModel));
var newViewModelObject = viewModelContainer.Resolve<IViewModelProduct>();
return newViewModelObject;
}
Simply using unity to construct an object from the interface base class. Whilst registering the type, the passed IProduct object has been set to the constructor of the new ViewModelProduct Instance.

Rhinomock non-primitive object in expectations

it seems comments can't support code
Lets say I call a method (e.g. SaveTicket) and have used constructor(e.g. Repository, Logging) to inject various mock interfaces. If that method calls another object and creates a non-primitive object inside that method. Is there any easy way to test the values of that non-primitive object?
I guess trying to replace that non-primitive object with property and injecting is possible, or Using LastCall.Constraints. Is there a better way?
Here is an example - in the below example - in order to verify
Repository.save(t);
is called with correct values of t I can
Do lastcall.constraints
lastcall.ignorearguments
Is there a better way?
CreateMyTicket(int ticketnumber, string name)
{
ticketobject t = new ticketObject(ticketnumber, name);
t.upgrade = ticketnumber+2;
Repository.save(t);
}
Let's take an example. Suppose that you have the following class and you want to unit test the CreateMyTicket method:
public class ClassToTest
{
public IRepository Repository { get; private set; }
public ClassToTest(IRepository repository)
{
Repository = repository;
}
public void CreateMyTicket(int ticketnumber, string name)
{
var t = new TicketObject(ticketnumber, name);
t.Upgrade = ticketnumber + 2;
Repository.Save(t);
}
}
This assumes that we have an IRepository interface:
public interface IRepository
{
void Save(TicketObject t);
}
and here's how a sample unit test could look like:
[TestMethod]
public void CreateMyTicketTest()
{
// arrange
var repositoryStub = MockRepository.GenerateStub<IRepository>();
var sut = new ClassToTest(repositoryStub);
var ticketNumber = 5;
var name = "John";
// act
sut.CreateMyTicket(ticketNumber, name);
// assert
repositoryStub.AssertWasCalled(
x => x.Save(
Arg<TicketObject>.Matches(t =>
t.Upgrade == 7 &&
t.Name == name &&
t.TicketNumber == ticketNumber
)
)
);
}
You should only test which methods was called on mocked dependencies (Repository, Logging). Verifying objects, returned from mocks, give you nothing (because you verify what you just created manually and set as return result).

C# Bestpractice: Writing a method that returns a value in depdency of the method parameter that is a part of the class itself

At first sorry for my really bad title! If you have a better title just change it or make a comment =)
I have this class:
public class Config
{
public Provider1 Provider1 { get; set; }
public Provider2 Provider2 { get; set; }
public Provider3 Provider3 { get; set; }
public Provider4 Provider4 { get; set; }
public Provider5 Provider5 { get; set; }
public int GetNumber(string provider)
{
...
}
}
Each provider has a Number property:
public interface IProvider
{
int Number{ get; set; }
}
In dependency of the provider I want to return the Number of the provider.
How would you do that?
I do not want to use a big switch block.
public interface IProvider
{
int Number {get;set;}
}
public class Config
{
public int GetNumber<T>() where T : IProvider
{
// code to find the provider you want
IProvider foundProvider = ProviderFactoryMethodHere(typeof(T));
return foundProvider.Number;
}
}
Now all of your provider classes need to implement the IProvider interface and you need to implement a factory that will return the correct provider to you given the type that you've requested in the generic method.
// Test code example
Config configImpl = new Config();
int numberOfProvider = configImpl.GetNumber<Provider1>();
Assert.Equal(1, numberOfProvider);
I'll add a simple ProviderFactoryMethod example. Note that we could also make this method generic instead of passing the type as a parameter, but I'll leave the example as is.
public IProvider ProviderFactoryMethodHere(Type providerRequested)
{
Dictionary <Type, IProvider> providerDict;
if (providerDict == null)
{
// populate dictionary with providers, keyed by their type
providerDict = new Dictionary<Type, IProvider>();
providerDict.Add(typeof(Provider1), new Provider1());
// repeat for all providers, this is pretty simple but definitely works
// we could use other ways of holding on to your provider instances
}
if (providerDict.HasKey(providerRequested))
{
return providerDict[providerRequested];
}
// could throw exception here if you want to use that kind of error
// handling, but we'll just return null for now
return null;
}
Cheers.
Add them to a dictionary keyed off the string that identifies the provider.
IDictionary<string, IProvider> providers = new Dictionary<string, IProvider>();
You can then get the values from the dictionary by checking if the dictionary contains the value passed into the GetNumber method. If it's there, you can just grab it out of the dictionary and call the Number property on the provider.
return providers[provider].Number;
Note that when you're defining the dictionary, IProvider needs to be the base class which all the providers inherit from.
Ideally you want all of your Providers to inherit from a single base class (or interface) that provides the Number of each.
abstract class Provider {
public int Number { get; set; }
}
class Provider1 : Provider { ... }
Then you can dump all of your Providers in a hash table keyed by whatever that string is you're using. For example:
public class Config
{
Dictionary<string, Provider> _providers = new Dictionary<string, Provider>();
// .. all of your providers ..
public int GetNumber(string provider)
{
if (!_providers.HasKey(provider))
throw ArgumentException();
return _providers[provider].Number;
}
}
Create an interface.
IGiveANumberbackable
{
GetNumber();
}
Implement this in your classes.
Call this method on your class instead of GetNumber()
Is the provider's number a property of a base class or interface that all providers implement, or is it a property of its position in the config class?
edit
If it's a property of the provider, then the right way to access it is through the provider. In other words, Config should return some child of IProvider (or whatever you call it), and the caller can then chain to its Number property.
edit
Part of the problem is that you have enumerated property names ("prop1", "prop2", etc). Why not replace this with an indexer or a method that takes an index?
Another issue is that you seem to want to look up the Number by provider name, but there's no place shown where a name exists. Do you mean the class name?

Categories