I am trying to implement a kind of dependency injection / singleton storage for my framework but cannot figure out the last steps because of all the generics and interfaces in the modules.
My infrastructure is composed on a stack of modules:
Base modules:
implement the base controllers and interfaces.
Here I define the repository patterns and interfaces and also the generic base classes for its implementation.
public interface IControllerBaseRead<T>
{
T Get(int Id);
List<T> GetAll();
List<T> Find(string sqlCondition, params object[] args);
}
public abstract class ControllerBaseRead<T> : IControllerBaseRead<T> where T : class
{
public virtual T Get(int id)
{
T item = null;
using (IDataContext context = DataContext.Instance())
{
var repository = context.GetRepository<T>();
item = repository.GetById(id);
}
return item;
}
public virtual List<T> Find(string sqlCondition, params object[] args)
{
IEnumerable<T> items = null;
using (IDataContext context = DataContext.Instance())
{
var repository = context.GetRepository<T>();
items = repository.Find(sqlCondition, args);
}
return items.EmptyIfNull().ToList();
}
}
Now, the second module has a table for employees so I define it's Model and Controller inheriting from the necessary interfaces. Model implements additional interfaces to define some common fields like autit info, IDs,...
[TableName("Employee")]
[PrimaryKey("Id", AutoIncrement = true)]
public class Employee : ContentAuditableIdEntity
{
public int? UserId { get; set; }
public int? OrgUnitId { get; set; }
public int? ManagerId { get; set; }
public string Status { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
public class EmployeeController : ControllerBase<Models.Employee>
{
}
I have been using this patters for some years now and it's working great as long as I can reference the different modules so they can interact with each other.
Now comes the challenge.
If I want to add some kind of abstraction on the Employee controller, I would create an abstract controller and abstract Model that the HR module could use and implement. So I created a new Module, called abstractions where I add the necessary interfaces:
public interface IEmployee : Interfaces.IContentAuditableIdEntity
{
int? UserId { get; set; }
int? OrganizationalUnitId { get; set; }
int? ManagerId { get; set; }
int? EmployeeMainRoleId { get; set; }
string Status { get; set; }
}
public interface IEmployeeController<TModel> : Interfaces.IControllerBase<TModel> where TModel : Models.IEmployee
{ }
As a next step I have changed the HR module so the employee module and controller compply with this new interface:
public class Employee : ContentAuditableIdEntity, IEmployee
{
(...)
}
public class EmployeeController : ControllerBase<Models.Employee>, IEmployeeController<Models.Employee>
{
}
Now, for the final steps, I have created a singleton class where I can store objects and resolve instances based on their types. The basic methods are as follows. One allows the registration os a callback to that returns a new instance of the given type and the other resolves-it:
public DependencyResolverInstance Add<TType>(Func<TType> factory){...}
public TType Resolve<TType>(){...}
Now, on the HR module I am trying to create an instance of the employee controller and store it as the abstraction type so it can be used from other modules without having to know or reference the HR module itself:
DependencyResolver.Instance.Add<Abstractions.HR.IEmployeeController<Abstractions.HR.IEmployee>>(() => new Controllers.EmployeeController());
I was hoping for this to work because I am creating a new EmployeeController that implements the abstract IEmployeeController with a model that implements IEmployee.
But it is not working because of the following error:
Cannot implicitly convert type 'Modules.HR.Controllers.EmployeeController' to 'Abstractions.HR.IEmployeeController<Abstractions.HR.IEmployee>'. An explicit conversion exists (are you missing a cast?)
Is there any way of correctly casting the specific instance of the controller to it's abstract Interface definition and keep complying with it's base implementation (base class)?
Thanks!!
Update
Just to be clear. My problem is not with DI itself. My problem is on How to convert from EmployeeController to IEmployeeController < IEmployee > .
EmployeeController implements IEmployeeController < Employee > and Employee implements IEmployee, but they are not compatible.
Related
Our webservice must return different types that may have one base type with some shared properties but with otherwise different properties.
Method may look like:
CreateObject(int typeID)
and depending on the typeID a different type of object would be returned. If this was no webservice, then an IOC container would do the trick. But in our scenario, the object must be created by the service and will actually be used be another service that will then pass the object to the business layer.
We are trying to avoid a lot of mapping and if possible the object types should only be defined in one place.
What would be a good design pattern to look for in this scenario?
Something like this does the trick (of course this can be nicyified with IOC etc.), the piece I was missing is the "KnownType" attribute:
[ServiceContract]
public interface IService1
{
[OperationContract]
AbstractResult GetAbstractData(int id);
}
[DataContract]
[KnownType(typeof(ConcreteResult1))]
[KnownType(typeof(ConcreteResult2))]
public abstract class AbstractResult
{
[DataMember]
public int ID { get; set; }
}
[DataContract]
public class ConcreteResult1 : AbstractResult
{
[DataMember]
public string Name { get; set; }
}
[DataContract]
public class ConcreteResult2 : AbstractResult
{
[DataMember]
public int Number { get; set; }
}
Simple example of a service method:
public class Service1 : IService1
{
public AbstractResult GetAbstractData(int id)
{
if (id == 1)
return new ConcreteResult1() { ID = 1, Name = "red" };
else
return new ConcreteResult2() { ID = 2, Number = 123 };
}
}
Preface: I am aware that there are a lot of questions and answers about covariance and contravariance but I'm still feeling muddled and not sure what solution to implement.
I have two interfaces whose implementations are intended to be used together in pairs. One provides the information about a sales item and one provides language dependent information for a sales item.
I do not have control over these interfaces:
public interface IItem
{
decimal Price { get; set; }
}
public interface IItemTranslation
{
string DisplayName { get; set; }
}
I also have two implementations of both these interfaces for a tangible GoodsItem as well as an intangible ServiceItem. Again, I do not have control over these interfaces:
public class GoodsItem : IItem
{
public decimal Price { get; set; } //implementation
public float ShippingWeightKilograms { get; set; } //Property specific to a GoodsItem
}
public class GoodsTranslation : IItemTranslation
{
public string DisplayName { get; set; } //implementation
public Uri ImageUri { get; set; } //Property specific to a GoodsTranslation
}
public class ServiceItem : IItem
{
public decimal Price { get; set; } //implementation
public int ServiceProviderId { get; set; } // Property specific to a ServiceItem
}
public class ServiceTranslation : IItemTranslation
{
public string DisplayName { get; set; } //implementation
public string ProviderDescription { get; set; } // Property specific to a ServiceTranslation
}
As I said, these are classes that I do not have control over. I want to create a generic list of these pairings (List<Tuple<IItem, IItemTranslation>>) but I cannot:
public class StockDisplayList
{
public List<Tuple<IItem, IItemTranslation>> Items { get; set; }
public void AddSomeStockItems()
{
Items = new List<Tuple<IItem, IItemTranslation>>();
var canOfBeans = new Tuple<GoodsItem, GoodsTranslation>(new GoodsItem(), new GoodsTranslation());
var massage = new Tuple<ServiceItem, ServiceTranslation>(new ServiceItem(), new ServiceTranslation());
Items.Add(canOfBeans); //illegal: cannot convert from 'Tuple<GoodsItem, GoodsTranslation>' to 'Tuple<IItem, IItemTranslation>'
Items.Add(massage); //illegal: cannot convert from 'Tuple<ServiceItem, ServiceTranslation>' to 'Tuple<IItem, IItemTranslation>' }
}
Question: Without changing my IItem and ITranslation classes or their derived types, what's the cleanest way to be able to pass around a generic list of these pairings without casting them back and forth between the interface and their type?
Caveat. I was trying to simplify the question but I'm not actually using Tuples. In reality I'm using a class like this:
public class ItemAndTranslationPair<TItem, TItemTranslation> where TItem : class, IItem where TItemTranslation : class, IItemTranslation
{
TItem Item;
TTranslation Translation;
}
and my services are returning strongly typed lists, like List<ItemAndTranslationPair<GoodsItem, GoodsTranslation>> and therefore when I add items to the 'generic' list it looks like:
var differentBrandsOfBeans = SomeService.GetCansOfBeans();
//above variable is of type IEnumerable<ItemAndTranslationPair<GoodsItem, GoodsTranslation>>
var items = new List<ItemAndTranslationPair<IItem, IItemTranslation>>();
items.AddRange(differentBrandsOfBeans);
You need to create the tuples using the interface types:
var canOfBeans = new Tuple<IItem, IItemTranslation>(new GoodsItem(), new GoodsTranslation());
var massage = new Tuple<IItem, IItemTranslation>(new ServiceItem(), new ServiceTranslation());
As you're storing them in a list of Tuple<IItem, IItemTranslation> this should be a problem for you.
Use the out modifier on the type parameter of the generic type to obtain covariance in that parameter.
In the current version of C#, this is not supported for class types, only interface types (and delegate types), so you would need to write an interface (notice use of out):
public interface IReadableItemAndTranslationPair<out TItem, out TItemTranslation>
where TItem : class, IItem
where TItemTranslation : class, IItemTranslation
{
TItem Item { get; }
TItemTranslation Translation { get; }
}
Note that the properties cannot have a set accessor since that would be incompatible with the covariance.
With this type, you can have:
var differentBrandsOfBeans = SomeService.GetCansOfBeans();
//above variable is of type
//IEnumerable<IReadableItemAndTranslationPair<GoodsItem, GoodsTranslation>>
var items = new List<IReadableItemAndTranslationPair<IItem, IItemTranslation>>();
items.AddRange(differentBrandsOfBeans);
It works because IEnumerable<out T> is covariant, and your type IReadableItemAndTranslationPair<out TItem, out TItemTranslation> is covariant in both TItem and TItemTranslation.
I have an interface which I need to mock:
public interface IDataAccess
{
List<StaffItem> GetStaff();
List<RankItem> GetRank();
List<FleetItem> GetFleet();
List<ContractItem> GetContract();
List<BaseItem> GetBase();
}
The problem is that each of the classes used for these lists have a common property. which must match, I am really struggling to create this mock while having a common like of Id's to allow me to test the class's which have this interface injected into to them.
Thanking you all in-advance.
AutoFixture allows to freeze specimens when a specific condition is met. The [Frozen] attribute receives a Matching parameter which determines when to freeze a specimen. In the sample below the id parameter is frozen when the staffItem.Id property is to be resolved. Then the same value is injected into rankItem.Id:
[Theory, AutoData]
public void MatchByIdTest(
[Frozen(Matching.PropertyName)]int id,
StaffItem staffItem,
RankItem rankItem)
{
Assert.Equal(staffItem.Id, rankItem.Id);
Assert.NotEqual(staffItem.SomeProp, rankItem.SomeProp);
}
public class StaffItem
{
public int Id { get; set; }
public int SomeProp { get; set; }
}
public class RankItem
{
public int Id { get; set; }
public int SomeProp { get; set; }
}
The same mechanism can be used in more advanced scenario with a mocking library, e.g. NSubstitute. The sample below uses AutoConfiguredNSubstituteCustomization which populates mocks with some data but injects the same id into all the Id properties:
[Theory, AutoConfigNSubstituteData]
public void MatchByIdTestWithAutoConfigNSubstitute(
[Frozen(Matching.PropertyName)]int id,
IDataAccess da)
{
var staff = da.GetStaff().First();
var rank = da.GetRank().First();
Assert.Equal(staff.Id, rank.Id);
Assert.NotEqual(staff.SomeProp, rank.SomeProp);
}
internal class AutoConfigNSubstituteDataAttribute : AutoDataAttribute
{
public AutoConfigNSubstituteDataAttribute()
: base(new Fixture()
.Customize(new AutoNSubstituteCustomization())
.Customize(new AutoConfiguredNSubstituteCustomization()))
{
}
}
Many tables in my database have common fields which I call 'audit' fields. They fields like - UserUpdateId, UserCreateId, DateUpdated, DateCreated, DateDeleted, RowGUID, as well as a common "Comments" table etc. In the database they are used to track who did what when. Additionally via the asp.net MVC 4 views they display these attributes to the user using common display templates (popup, mouseover etc.).
Currently, I put these properties into a [Serializable()] CommonAttributesBase class. Which I then initialize in all the models that should inherit those properties. Admittedly this is a little clunky and inefficient as my CommonAttribute class makes calls to the repository and the initialization seems like more code than necessary.
I would appreciate suggestions on how to implement this in the best way.
[Serializable()]
public class CommonAttributesBase
{
#region Notes
public Boolean AllowNotes { get; set; }
[UIHint("NoteIcon")]
public NoteCollection NoteCollection
{
get
{
if (!AllowNotes) return null;
INoteRepository noteRepository = new NoteRepository();
var notes = noteRepository.FindAssociatedNotes(RowGUID);
return new NoteCollection { ParentGuid = RowGUID, Notes = notes, AuditString = AuditTrail };
}
}
#region Audit Trail related
public void SetAuditProperties(Guid rowGuid, Guid insertUserGuid, Guid updateUserGuid, Guid? deleteUserGuid, DateTime updateDate, DateTime insertDate, DateTime? deleteDate)
{
RowGUID = rowGuid;
InsertUserGUID = insertUserGuid;
UpdateUserGUID = updateUserGuid;
DeleteUserGUID = deleteUserGuid;
UpdateDate = updateDate;
InsertDate = insertDate;
DeleteDate = deleteDate;
}
[UIHint("AuditTrail")]
public string AuditTrail
{
get
{
...code to produce readable user audit strings
return auditTrail;
}
}
...additional methods
}
In another class
public partial class SomeModel
{
private CommonAttributesBase _common;
public CommonAttributesBase Common
{
get
{
if (_common == null)
{
_common = new CommonAttributesBase { AllowNotes = true, AllowAttachments = true, RowGUID = RowGUID };
_common.SetAuditProperties(RowGUID, InsertUserGUID, UpdateUserGUID, DeleteUserGUID, UpdateDate, InsertDate, DeleteDate);
}
return _common;
}
set
{
_common = value;
}
}
...rest of model
}
For me, I prefer to use different interfaces for each type (audit or note), and use decorator to retrieve those related data, instead of embedding those in the common class:
public class Note
{
//Node properties
}
public class AuditTrail
{
//Audit trail properties
}
public interface IAuditable
{
AuditTrail AuditTrail { get; set; }
}
public interface IHaveNotes
{
IList<Note> Notes { get; set; }
}
public class SomeModel : IAuditable, IHaveNotes
{
public IList<Note> Notes { get; set; }
public AuditTrail AuditTrail { get; set; }
public SomeModel()
{
Notes = new List<Note>();
}
}
public class AuditRepository : IRepository<T> where T : IAuditable
{
private IRepository<T> _decorated;
public AuditRepository(IRepository<T> decorated)
{
_decorated = decorated;
}
public T Find(int id)
{
var model = _decorated.Find(id);
model.Audit = //Access database to get audit
return model;
}
//Other methods
}
public class NoteRepository : IRepository<T> where T : IHaveNotes
{
private IRepository<T> _decorated;
public NoteRepository(IRepository<T> decorated)
{
_decorated = decorated;
}
public T Find(int id)
{
var model = _decorated.Find(id);
model.Notes = //Access database to get notes
return model;
}
//Other methods
}
Advantages is that the client will be able to choose to load audit/note or not, the logic of audit and note are also separated from the main entity repository.
What you're doing is basically composition. As others have stated, there's many ways to accomplish what you're looking for, some better than others, but each method depends on the needs of your application, of which only you can speak to.
Composition
Composition involves objects having other objects. For example, if you were going to model a car, you might have something like:
public class Car
{
public Engine Engine { get; set; }
}
public class Engine
{
public int Horsepower { get; set; }
}
The benefit to this approach is that your Car ends up with a Horsepower property via Engine, but there's no inheritance chain. In other words, your Car class is free to inherit from another class while not effecting this property or similar properties. The problems with this approach is that you have to involve a separate object, which in normally is not too troubling, but when combined when tied back to a database, you're now talking about having a foreign key to another table, which you'll have to join in order to get all the class' properties.
Entity Framework allows you to somewhat mitigate this effect by using what it calls "complex types".
[ComplexType]
public class Engine
{
...
}
The properties of complex types are mapped onto the table for the main class, so no joins are involved. However, because of this, complex types have certain limitations. Namely, they cannot contain navigation properties -- only scalar properties. Also, you need to take care to instantiate the complex type or you can run into problems. For example, any nulled navigation property is not validated by the modelbinder, but if you have a property on your complex type that is required (which results in a property on your main class' table that is non-nullable), and you save your main class while the complex type property is null, you'll get an insertion error from the database. To be safe you should always do something like:
public class Car
{
public Car()
{
Engine = new Engine();
}
}
Or,
public class Car
{
private Engine engine;
public Engine Engine
{
get
{
if (engine == null)
{
engine = new Engine();
}
return engine;
}
set { engine = value; }
}
}
Inheritance
Inheritance involves deriving your class from a base class and thereby getting all the members of that base class. It's the most straight-forward approach, but also the most limiting. This is mostly because all of the .NET family of languages only allow single inheritance. For example:
public class Flyer
{
public int WingSpan { get; set; }
}
public class Walker
{
public int NumberOfLegs { get; set; }
}
public class Swimmer
{
public bool HasFlippers { get; set; }
}
public class Duck : ????
{
...
}
That's a bit contrived, but the point is that Duck is all of a Flyer, Walker and Swimmer, but it can only inherit from one of these. You have to be careful when using inheritance in languages that only allow single inheritance to make sure that what you inherit from is the most complete base class possible, because you won't be able to easily diverge from this.
Interfaces
Using interfaces is somewhat similar to inheritance, but with the added benefit that you can implement multiple interfaces. However, the downside is that the actual implementation is not inherited. In the previous example with the duck, you could do:
public class Duck : IFlyer, IWalker, ISwimmer
However, you would be responsible for implementing all the members of those interfaces on your Duck class manually, whereas with inheritance they just come through the base class.
A neat trick with interfaces and .NET's ability to extend things is that you can do interface extensions. These won't help you with things like properties, but you can move off the implementation of some of the class' methods. For example:
public static class IFlyerExtensions
{
public static string Fly(this IFlyer flyer)
{
return "I'm flying";
}
}
Then,
var duck = new Duck();
Console.WriteLine(duck.Fly());
Just by implementing IFlyer, Duck gets a Fly method, because IFlyer was extended with that method. Again, this doesn't solve every problem, but it does allow interfaces to be somewhat more flexible.
There's a couple different ways you could do something like this. I personally haven't worked with EF so I can't speak in regards to how it will work.
Option One: Interfaces
public interface IAuditable
{
Guid RowGUID { get; }
Guid InsertUserGUID { get; }
Guid UpdateUserGUID { get; }
Guid DeleteUserGUID { get; }
DateTime UpdateDate { get; }
DateTime InsertDate { get; }
DateTime DeleteDate { get; }
}
Of course you can change it to get and set if your use cases need that.
Option Two: Super/base classes
public abstract class AuditableBase
{
// Feel free to modify the access modifiers of the get/set and even the properties themselves to fit your use case.
public Guid RowGUID { get; set;}
public Guid InsertUserGUID { get; set;}
public Guid UpdateUserGUID { get; set;}
public Guid DeleteUserGUID { get; set;}
public DateTime UpdateDate { get; set;}
public DateTime InsertDate { get; set;}
public DateTime DeleteDate { get; set;}
// Don't forget a protected constructor if you need it!
}
public class SomeModel : AuditableBase { } // This has all of the properties and methods of the AuditableBase class.
The problem with this is that if you cannot inherit multiple base classes, but you can implement multiple interfaces.
Is it possible to create generic restriction in C# using where to select only classes, who have Field with some name.
for example, I have AbstractService<T>
and I have a method IEnumerable<T> ProvideData(userId);
inside provide data I should select only instances with the same user bla-bla-bla.Where(d => d.UserId == userId). But d.UserId could not be resolved. How it possible to resolve this?
IMPORTANT: I can't inherit T from class or interface, which have UserID field.
An interface is what your are looking for:
public interface IWithSomeField
{
int UserId { get; set; }
}
public class SomeGenericClasss<T>
: where T : IWithSomeField
{
}
public class ClassA : IWithSomeField // Can be used in SomeGenericClass
{
int UserId { get; set; }
}
public class ClassB // Can't be used in SomeGenericClass
{
}
[Edit] As you edited your question to state you cannot change class to implement an interface, here is some alternatives, but none relies on generic constraint :
Check the type in the constructor :
code :
public class SomeClass<T>{
public SomeClass<T>()
{
var tType = typeof(T);
if(tType.GetProperty("UserId") == null) throw new InvalidOperationException();
}
}
Use code contract invariant (not sure about the syntax) :
code :
public class SomeClass<T>{
[ContractInvariantMethod]
private void THaveUserID()
{
Contract.Invariant(typeof(T).GetProperty("UserId") != null);
}
}
Extend existing classes with partial classes
If your source classes are generated, you can cheat. I used this technique with lots of Web References having the same kind of parameter objects
Imagine the Web references produced this proxy code :
namespace WebServiceA {
public class ClassA {
public int UserId { get; set; }
}
}
namespace WebServiceB {
public partial class ClassB {
public int UserId { get; set; }
}
}
You can wrap them using in your own code:
public interface IWithUserId
{
public int UserId { get; set; }
}
public partial class ClassA : IWithUserId
{
}
public partial class ClassB : IWithUserId
{
}
then, for your service, you can instantiate AbstractService for any of the Class of the several web services :
public class AbstractService<T> where T : IWithUserId
{
}
This technique works great but only applies when you can extend class in the same project because of the partial keyword trick.