Create Instance of a class from interface which it implements - c#

Hi I am trying to build a generic UoWFactory which creates a UnitOfWork(there will be one default unitofwork and multiple custom implementaitons as well). So far I was able to create factory method which creates default UoW and returns it. I have modify the following method to return specified UoW depending on the parameter passed.
Current implementation
private BaseResult<IUnitOfWork> GetUnitOfWorkByCompiledModel<IUnitOfWork>(DbCompiledModel compiledModel)
{
return new BaseResult<IUnitOfWork>
{
Payload = new DbUnitOfWork(_context, _dbRepository, _mapper, _entityMapper)
};
}
I wish to have something like this
private BaseResult<TUoW> GetUnitOfWorkByCompiledModel<IUnitOfWork>(DbCompiledModel compiledModel) where TUoW :Class
{
return new BaseResult<TUoW>
{
//Create instance of type TUoW where TUoW can be IUnitOfWork, ICustomUnitOfWork etc
//DbUnitOfWork implements IUnitOfWork and CustomUnitOfWork implements ICustomUnitOfWork
//All the TUoW will have constructors with identical parmeters
};
}
Create an instance of class is straight forward
Activator.CreateInstance (Type type, object[] args);
But if I pass Interface type as a parameter how to create instance of DbUnitOfWork or CustomUnitOfWork.
eg:-
GetUnitOfWorkByCompiledModel<IUnitOfWork>(compiledModel);
GetUnitOfWorkByCompiledModel<ICustomUnitOfWork>(compiledModel);

Parameterless constructors
What you want is possible, except for one thing: you can't use non-default constructors with generic type arguments. You can't avoid that.
Part of the issue here is that you can't enforce specific constructor method signatures from an interface, so there is no way to guarantee that all implementation of IUnitOfWork are going to have the same constructor.
The simplest solution here is to step away from using constructors and instead use object initialization:
public interface IUnitOfWork
{
Foo Foo { get; set; }
}
private BaseResult<TUnitOfWork> GetUnitOfWorkByCompiledModel<TUnitOfWork>(DbCompiledModel compiledModel) where TUnitOfWork : IUnitOfWork, new()
{
return new BaseResult<TUnitOfWork>
{
Payload = new TUnitOfWork()
{
Foo = myFoo
};
};
}
I think this suits your expectations while being a minimal change.
Resolving interfaces
But if I pass Interface type as a parameter how to create instance of DbUnitOfWork or CustomUnitOfWork. eg
GetUnitOfWorkByCompiledModel<IUnitOfWork>(compiledModel);
GetUnitOfWorkByCompiledModel<ICustomUnitOfWork>(compiledModel);
If you intend to use interface types without concrete types, then the above answer is incomplete.
Regardless of the generic type issue, if you want to resolve an interface into a concrete type, you need to register which concrete type you want to use.
This is most commonly done via a Dependency Injection framework. These framework ask you to register all necessary types, e.g. a .NET Core example:
services.AddTransient<IUnitOfWork, MyUnitOfWork>();
services.AddTransient<ICustomUnitOfWork, MyCustomUnitOfWork>();
And the framework will then use this registration to automatically fill in constructor parameters for you:
public class Example
{
public Example(ICustomUnitOfWork uow)
{
}
}
The good practice approach here requires you to thread this dependency injection through your entire framework so you never need to call any constructor explicitly (and instead have the DI framework do it for you).
It is possible to use a service locator, which is essentially a DI framework that you call at-will. A small example of usage would be:
private BaseResult<TUnitOfWork> GetUnitOfWorkByCompiledModel<TUnitOfWork>(DbCompiledModel compiledModel) where TUnitOfWork : IUnitOfWork, new()
{
var uow = myServiceLocator.Get<TUnitOfWork>();
uow.Foo = myFoo;
return new BaseResult<TUnitOfWork>
{
Payload = uow;
};
}
This creates an instance of whichever concrete type was registered to the interface you're using as the generic parameter.
However, service locators are generally considered to be an anti-pattern, and I would strongly suggest that you avoid favor a cleaner IoC approach than this.
I can't elaborate fully on dependency injection in scope of a single StackOverflow answer. I suggest you look up dependency injection as it does exactly what you're expecting (getting a concrete type by referencing an interface)

This will be work if DbUnitOfWork Class has right name of values
What you want to change
Payload = new DbUnitOfWork(_context, _dbRepository, _mapper, _entityMapper);
Change as
Payload = new DbUnitOfWork() {
context = _context,
dbRepoitory = _dbRepository,
mapper = _mapper,
entityMapper = _entityMapper
};
hope this work.

Related

Ninject Dependency Injection - Two Concrete classes

I am learning Ninject for dependency injection and have a use case where two classes implement the same interface in a WPF MVVM applicaiton. In my research the dependencies can be bound using contextual bindings, however I am unsure of how that would work in this scenario.
For example:
public interface IModifyContent {
string ModifyOperation();
}
public class UpdateContent : IModifyContent {
public string ModifyOperation() {
return "This is the update operation";
}
}
public class DeleteContent : IModifyContent {
public string ModifyOperation() {
return "This is the delete operation";
}
}
public class ModifyFile {
private IFileManager _fileManager;
private IModifyContent _modifyContent;
public ModifyFile(IFileManager fileManager, IModifyContent modifyContent)
{
_fileManager = _fileManager;
_modifyContent = modifyContent;
}
public void Modify()
{
var fileContent = _fileManager.ReadFileContents(); // Returns file content
var result = _modifyContent.ModifyOperation(); // ModifyOperation would actually modify content in some way...
// Do stuff with result
}
}
Then the binding would look something like this:
Bind<IModifyContent>().To<UpdateContent>();
Bind<IModifyContent>().To<DeleteContent>();
// Other bindings
In this my thinking is as follows:
ModifyFile class is used for common funcitonaility when modifying a file, whereas the two concrete implementations of IModifyContent define the unique behaviour that can occur for the different operations.
Depending on what calls/ invokes ModifyFile I want to pass in a different concrete implementation of IModifyContent. I.e When calling from update business logic or view model, then the concrete UpdateContent should be passed as the dependency to ModifyFile.
Firstly is this a good design approach to avoid repeating common logic and secondly how can I inject the correct concrete implementation depending on what class/ invokes ModifyFile?
There is a way through which you can achieve this !!!
You can register dependencies with specific name.
IKernel ninjectKernel = new StandardKernel();
// Defining Bindings with specific names
ninjectKernel.Bind<IModifyContent>().To<UpdateContent>().Named("Update");
ninjectKernel.Bind<IModifyContent>().To<DeleteContent>().Named("Delete");
You can resolved these dependencies at compile time as shown below:
// Resolving dependencies using binding name
IModifyContent updateContent = ninjectKernel.Get<IModifyContent>("Update");
IModifyContent deleteContent = ninjectKernel.Get<IModifyContent>("Delete");
Once resolve they can be use to execute their codes. Below is the sample code which refers to the implementation that you have provided.
Console.WriteLine(updateContent.ModifyOperation());
Console.WriteLine(deleteContent.ModifyOperation());
// Output
// This is the update operation
// This is the delete operation
You can resolve such dependencies at run time as well.
For more information refer to the following link:
https://github.com/ninject/Ninject/wiki/Contextual-Binding
I think that if your two concrete classes are from different business flows,
you can register them as concrete classes and not by abstraction.
I mean you can register
Bind<UpdateContent>().To<UpdateContent>();
Bind<DeleteContent>().To<DeleteContent>();
And In your BusinessLogic class you can ask for concrete classes.
TLDR: The fact that two classes have the Interface, don't mean you must use them from there abstraction.

Dependency Injection and Generics

I'm having trouble with getting generics and DI to work together in an MVC Core project. I have a generic class (this is just a fragment). I need to initialize Input and Output because of how these are used in other parts of the code, so I'm using Activator to provide initial values and the new() constraint.
public class Message<TIn, TOut> :
where TIn : class, IMessagePart, new()
where TOut : class, IMessagePart, new() {
public Message(){}
public Message(TIn inpart, TOut outpart) {
Input = inpart;
Output = outpart;
}
public TIn Input { get; set; } = (TIn)Activator.CreateInstance(typeof(TIn));
public TOut Output { get; set; } = (TOut)Activator.CreateInstance(typeof(TOut));
}
I have other classes that are used by this, and they have some static utility classes. I'm trying to replace these static classes using DI.
public class Project : IMessagePart{
int y = 1;
var x = StaticUtilityClass.StaticMethod(y);
}
is used like this
var projectMessage = new Message<Project, Project>();
I'm converting the static utility classes to instance classes and injecting them. I'm using the built-in .Net core container. I converted the utilities to instance classes and registered them as concrete singletons in the container. For most things I can just do the normal-
public class SomeClass{
private readonly UtilityClass _utility;
public SomeClass(UtilityClass utility){
_utility = utility;
var x = _utility.Method(1);
}
Things work fine until I get to the generics. I can't do constructor injection on projectMessage, because the generic needs to new it up and it has the new() constraint, so I need a parameterless constructor. If I add just the an injecting constructor I get
'Project' must be a non-abstract type with a public parameterless
constructor in order to use it as parameter 'TIn' in the generic type
or method 'Message'.
and if I add both constructors Activator is only going to call the one without parameters, so DI isn't invoked. I tried using the overload of CreateInstance a few different ways, but no luck tricking it.
Any suggestions here? I don't know if I should stay with statics, try some sort of service locator approach, or if there is a different way to writing the generic.
The answer to why you are getting the error you're seeing is the new() constraints. That specifies that the parameter must have a public parameterless constructor. Which is exactly what your error says. Removing that constraint should fix that error. However, you still have another issue if you want to use DI.
Aside from IMessagePart none of your classes have backing interfaces. In order to use DI effectively you need to define an IMessage, IProject etc. Then your container can create specific instances at runtime, rather than using the Activators like you are now. So your Message declaration would look like:
public class Message<TIn, TOut> : IMessage,
where TIn : class, IMessagePart
where TOut : class, IMessagePart
{
public TIn input { get; set; }
public TOut output { get; set; }
public Message(TIn inpart, TOut outpart) {
this.input = inpart;
this.output = outpart;
}
}
You would setup your DI container something like:
public Startup()
{
var container = new DiContainer(); // I know this is the wrong name; I'm not familiar with the built in container naming and functionality.
container.Register<IMessage>();
container.Register<IMessagePart>();
container.Register<IProject>();
// Register other stuff here
}
Change the syntax there for your specific container. You also have the option of registering your instances something like:
container.Register<Message>(() => Message(part1, part2));
so that you specifically inject a Message that is newed up at Startup time, but that's not really ideal in most cases. Usually you want your DI container to dynamically create an instance as needed (hence the interfaces), rather than using a single concrete instantiation. There are exceptions of course; a SQL connection is one common one.

How to decorate class that relies on a runtime value for creation

I'm brand new to using Simple Injector although I have been using Ninject for a long time, so I am comfortable with DI in general. One thing that attracted me to want to use Simple Injector was the ease of use of Decorators.
I have been able to successfully use decorators with Simple Injector in all normal cases where the dependencies are resolved when the service is requested. However, I am having a hard time figuring out if there is a way to get my decorators applied in a case when the service must be constructed using a runtime value.
In Ninject, I could pass a ConstructorArgument to the kernel.Get<IService> request that could be inherited down the chain of N decorators all the way to the "real" implementing class. I cannot figure out a way to replicate that using Simple Injector.
I have put some very basic code below to illustrate. What I would want to do in the real world would be to pass an IMyClassFactory instance into other classes in my application. Those other classes could then use it to create IMyClass instances using the IRuntimeValue they would provide. The IMyClass instance they got from the IMyClassFactory would be decorated automatically by the registered decorators.
I know I could manually apply my decorator(s) in my IMyClassFactory or any Func<IMyClass> I could come up with, but I would like it to "just work".
I keep going around and around trying to abstract out the MyClass construction, but I can't figure out how to get it to resolve with the IRuntimeValue constructor argument and be decorated.
Am I overlooking an obvious solution?
using System;
using SimpleInjector;
using SimpleInjector.Extensions;
public class MyApp
{
[STAThread]
public static void Main()
{
var container = new Container();
container.Register<IMyClassFactory, MyClassFactory>();
container.RegisterDecorator(typeof (IMyClass), typeof (MyClassDecorator));
container.Register<Func<IRuntimeValue, IMyClass>>(
() => r => container.GetInstance<IMyClassFactory>().Create(r));
container.Register<IMyClass>(() => ?????)); // Don't know what to do
container.GetInstance<IMyClass>(); // Expect to get decorated class
}
}
public interface IRuntimeValue
{
}
public interface IMyClass
{
IRuntimeValue RuntimeValue { get; }
}
public interface IMyClassFactory
{
IMyClass Create(IRuntimeValue runtimeValue);
}
public class MyClassFactory : IMyClassFactory
{
public IMyClass Create(IRuntimeValue runtimeValue)
{
return new MyClass(runtimeValue);
}
}
public class MyClass : IMyClass
{
private readonly IRuntimeValue _runtimeValue;
public MyClass(IRuntimeValue runtimeValue)
{
_runtimeValue = runtimeValue;
}
public IRuntimeValue RuntimeValue
{
get
{
return _runtimeValue;
}
}
}
public class MyClassDecorator : IMyClass
{
private readonly IMyClass _inner;
public MyClassDecorator(IMyClass inner)
{
_inner = inner;
}
public IRuntimeValue RuntimeValue
{
get
{
return _inner.RuntimeValue;
}
}
}
Edit 1:
Ok, thanks to Steven for the great answer. It has given me a couple of ideas.
Maybe to make it a little more concrete though (although not my situation, more "classic"). Say I have an ICustomer that I create at runtime by reading a DB or deserializing from disk or something. So I guess that would be considered a "newable" to quote one of the articles Steven linked. I would like to create an instance of ICustomerViewModel so I can display and manipulate my ICustomer. My concrete CustomerViewModel class takes in an ICustomer in its constructor along with another dependency that can be resolved by the container.
So I have an ICustomerViewModelFactory that has a .Create(ICustomer customer) method defined which returns ICustomerViewModel. I could always get this working before I asked this question because in my implementation of ICustomerViewModelFactory I could do this (factory implemented in composition root):
return new CustomerViewModel(customer, container.GetInstance<IDependency>());
My issue was that I wanted my ICustomerViewModel to be decorated by the container and newing it up bypassed that. Now I know how to get around this limitation.
So I guess my follow-up question is: Is my design wrong in the first place? I really feel like the ICustomer should be passed into the constructor of CustomerViewModel because that demonstrates intent that it is required, gets validated, etc. I don't want to add it after the fact.
Simple Injector explicitly lacks support for passing on runtime values through the GetInstance method. Reason for this is that runtime values should not be used when the object graph is constructed. In other words, the constructors of your injectables should not depend on runtime values. There are several problems with doing that. First of all, your injectables might need to live much longer than those runtime values do. But perhaps more importantly, you want to be able to verify and diagnose your container's configuration and that becomes much more troublesome when you start using runtime values in the object graphs.
So in general there are two solutions for this. Either you pass on the runtime value through the method call graph or you create a 'contextual' service that can supply this runtime value when requested.
Passing on the runtime value through the call graph is especially a valid solution when you practice architectures like this and this where you pass on messages through your system or when the runtime value can be an obvious part of the service's contract. In that case it is easy to pass on the runtime value with the message or the method and this runtime value will also pass through any decorator on the way through.
In your case this would mean that the factory creates the IMyService without passing in the IRuntimeValue and your code passes this value on to the IMyService using the method(s) it specifies:
var service = _myServiceFactory.Create();
service.DoYourThing(runtimeValue);
Passing through the runtime value through the call graph however is not always a good solution. Especially when this runtime value should not be part of the contract of the message that is sent. This especially holds for contextual information use as information about the current logged in user, the current system time, etc. You don't want to pass this information through; you just want it to be available. We don't want this, because this would give an extra burden to the consumers of passing the right value every time, while they probably shouldn't even be able to change this information (take the user in who's context the request is executed for instance).
In that case you should define service that can be injected and allows retrieving this context. For instance:
public interface IUserContext {
User CurrentUser { get; }
}
public interface ITimeProvider {
DateTime Now { get; }
}
In these cases the current user and the current time aren't injected directly into a constructor, but instead these services are. The component that needs to access the current user can simply call _userContext.CurrentUser and this will be done after the object is constructed (read: not inside the constructor). Thus: in a lazy fashion.
This does mean however that the IRuntimeValue must be set somewhere before MyClass gets invoked. This probably means you need to set it inside the factory. Here's an example:
var container = new Container();
var context = new RuntimeValueContext();
container.RegisterSingle<RuntimeValueContext>(context);
container.Register<IMyClassFactory, MyClassFactory>();
container.RegisterDecorator(typeof(IMyClass), typeof(MyClassDecorator));
container.Register<IMyClass, MyClass>();
public class RuntimeValueContext {
private ThreadLocal<IRuntimeValue> _runtime;
public IRuntimeValue RuntimeValue {
get { return _runtime.Value; }
set { _runtime.Value = value; }
}
}
public class MyClassFactory : IMyClassFactory {
private readonly Container _container;
private readonly RuntimeValueContext context;
public MyClassFactory(Container container, RuntimeValueContext context) {
_container = container;
_context = context;
}
public IMyClass Create(IRuntimeValue runtimeValue) {
var instance = _container.GetInstance<IMyClass>();
_context.RuntimeValue = runtimeValue;
return instance;
}
}
public class MyClass : IMyClass {
private readonly RuntimeValueContext _context;
public MyClass(RuntimeValueContext context) {
_context = context;
}
public IRuntimeValue RuntimeValue { get { return _context.Value; } }
}
You can also let the MyClass accept the IRuntimeValue and make the following registration:
container.Register<IRuntimeValue>(() => context.Value);
But the disallows verifying the object graph, since Simple Injector will ensure that registrations never return null, but context.Value will be null by default. So another option is to do the following:
container.Register<IMyClass>(() => new MyClass(context.Value));
This allows the IMyClass registration to be verified, but will during verification still create a new MyClass instance that is injected with a null value. If you have a guard clause in the MyClass constructor, this will fail. This registration however disallows MyClass to be auto-wired by the container. Auto-wiring that class can come in handy when you've got more dependencies to inject into MyClass for instance.

Dependency injection with multiple repositories

I have a wcf service and on the client i have:
var service = new ServiceReference1.CACSServiceClient()
The actual service code is:
public CACSService() : this(new UserRepository(), new BusinessRepository()) { }
public CACSService(IUserRepository Repository, IBusinessRepository businessRepository)
{
_IRepository = Repository;
_IBusinessRepository = businessRepository;
}
So, all this works fine, but i don't like how i am newing up all the repositories at the same time because the client code might not need to new up the UserRepository and only interested in newing up the BusinessRepository. So, is there a way to pass in something to this code:
var service = new ServiceReference1.CACSServiceClient()
to tell it which repository to new up based on the code that is calling the service or any other advice i need to go about when designing the repositories for my entity framework. Thankx
The beauty of pure DI is that you shouldn't worry about the lifetimes of your dependencies, because these are managed for you by whoever supply them (a DI Container, or some other code you wrote yourself).
(As an aside, you should get rid of your current Bastard Injection constructors. Throw away the parameterless constructor and keep the one that explicitly advertises its dependencies.)
Keep your constructor like this, and use _IRepository and _IBusinessRepository as needed:
public CACSService(IUserRepository Repository, IBusinessRepository businessRepository)
{
_IRepository = Repository;
_IBusinessRepository = businessRepository;
}
If you worry that one of these repositories are not going to be needed at run-time, you can inject a lazy-loading implementation of, say, IUserRepsository instead of the real one you originally had in mind.
Let's assume that IUserRepository looks like this:
public interface IUserRepository
{
IUser SelectUser(int userId);
}
You can now implement a lazy-loading implementation like this:
public class LazyUserRepository : IUserRepository
{
private IUserRepository uRep;
public IUser SelectUser(int userId)
{
if (this.uRep == null)
{
this.uRep = new UserRepository();
}
return this.uRep.SelectUser(userId);
}
}
When you create CACService, you can do so by injecting LazyUserRepository into it, which ensures that the real UserRepository is only going to be initialized if it's needed.
The beauty of this approach is that you don't have to do this until you need it. Often, this really won't be necessary so it's nice to be able to defer such optimizations until they are actually necessary.
I first described the technique of Lazy Dependencies here and here.
Instead of instantiating ("newing up") the repositories on construction, you could lazy load them in their properties. This would allow you to keep your second constructor, but have your first constructor do nothing.
The user could then assign these, as needed, otherwise.
For example:
public class CACSService
{
public CACSService() {}
public CACSService(IUserRepository Repository, IBusinessRepository businessRepository)
{
_IRepository = Repository;
_IBusinessRepository = businessRepository;
}
private IUserRepository _IRepository;
public IUserRepository Repository
{
get {
if (this._IRepository == null)
this._IRepository = new UserRepository();
return this._IRepository;
}
}
// Add same for IBusinessRepository
}
Do your repositories have object-level state? Probably not, so create them as singletons and have a DI container provide them to CACService.
Otherwise, are they actually expensive to create? If not, creating a new one per request has negligible cost compared to the RPC and database operations.
Using the Ninject dependency injection container, your CACService might look like the following. Other DI containers have equally succinct mechanisms of doing this.
public class CACSService
{
public CACService
{
// need to do this since WCF creates us
KernelContainer.Inject( this );
}
[Inject]
public IUserRepository Repository
{ set; get; }
[Inject]
public IBusinessRepository BusinessRepository
{ set; get; }
}
And during your application startup, you would tell Ninject about these types.
Bind<IUserRepository>().To<UserRepository>().InSingletonScope();
Bind<IBusinessRepository>().To<BusinessRepository>().InSingletonScope();
Preface: This is a general guide to dependency inversion. If you need the default constructor to do the work (e.g. if it is new'ed up by reflection or something else), then it'll be harder to do this cleanly.
If you want to make your application configurable, it means being able to vary how your object graph is constructed. In really simple terms, if you want to vary an implementation of something (e.g. sometimes you want an instance of UserRepository, other times you want an instance of MemoryUserRepository), then the type that uses the implementation (CACService in this case) should not be charged with newing it up. Each use of new binds you to a specific implementation. Misko has written some nice articles about this point.
The dependency inversion principle is often called "parametrise from above", as each concrete type receives its (already instantiated) dependencies from the caller.
To put this into practice, move the object creation code out of the CACService's parameterless constructor and put it in a factory, instead.
You can then choose to wire up things differently based on things like:
reading in a configuration file
passing in arguments to the factory
creating a different type of factory
Separating types into two categories (types that create things and types that do things) is a powerful technique.
E.g. here's one relatively simple way of doing it using a factory interface -- we simply new up whichever factory is appropriate for our needs and call its Create method. We use a Dependency Injection container (Autofac) to do this stuff at work, but it may be overkill for your needs.
public interface ICACServiceFactory
{
CACService Create();
}
// A factory responsible for creating a 'real' version
public class RemoteCACServiceFactory : ICACServiceFactory
{
public CACService Create()
{
return new CACService(new UserRepository(), new BusinessRepository());
}
}
// Returns a service configuration for local runs & unit testing
public class LocalCACServiceFactory : ICACServiceFactory
{
public CACService Create()
{
return new CACService(
new MemoryUserRepository(),
new MemoryBusinessRepository());
}
}

C# - Type Parameters in Constructor - No Generics

I have a class that I am trying to do unit tests on. The class is a WCF Service Class. (Making it a generics class is not my goal.)
I have a data access layer (DAL) type (called UserDAL) that is instantiated in many methods. To get these methods under test, I need to get this local variables mocked. (Each instance of UserDAL has method specific value in it, so changing it a class level variable would result in messy code, so I would rather not do that.)
What I am thinking would be nice is to overload the constructor and pass in a type to use in the local methods. The empty param constructor would still create a normal UserDAL, but the overloaded one would have a mock type that implements IUserDAL.
I am not sure of the syntax to say I want to pass in a type. Note that I am not trying to pass in a variable, but a type.
Example:
public class MyWCFClass: IMyWCFClass
{
private TypeParam _myUserDALType;
public MyWCFClass()
{
_myUserDALType = UserDAL;
}
public MyWCFClass(TypeParam myUserDALType)
{
_myUserDALType = myUserDALType;
}
//methods to use it
public MyMethod()
{
IUserDAL userDAL = new _myUserDALType();
//Call method in IUserDAL
userDAL.CreateUser();
}
// Several similar methods that all need a different UserDAL go here
.....
}
So, I don't know what kind of type TypeParam is (I made that up) or if this kind of think is even possible.
If you have a non generics solution that would be great.
What you are really looking for is Dependency Injection, but you can do this by passing in a Type argument and then using Activator.CreateInstance(Type) to create the object when you need it.
As far as doing real DI (which will make doing this testing a lot easier), I know that Spring.Net works reasonable well.
You mean Type, using Activator.CreateInstance to create instances:
public class MyWCFClass: IMyWCFClass
{
private Type _myUserDALType;
public MyWCFClass()
{
_myUserDALType = typeof(UserDAL);
}
public MyWCFClass(Type myUserDALType)
{
_myUserDALType = myUserDALType;
}
//methods to use it
public void MyMethod()
{
IUserDAL userDAL = (IUserDAL) Activator.CreateInstance(_myUserDALType );
//Call method in IUserDAL
userDAL.CreateUser();
}
}
Use a Type, and use Activator.CreateInstance to instantiate it:
private Type _myUserDALType;
IUserDAL userDAL = Activator.CreateInstance(_myUserDALType) as IUserDAL;
Your real problem is not in the generics or lack thereof. Your real problem is that MyWFCClass is calling both new and the method. As per Misko Hevery, you get the best testability by separating classes that call new from classes that implement logic. Instead of having MyWFCClass somehow know the type that you want to implement and using reflection, just pass the IUserDal object to the constructor, allowing the test harness to pass in a mock object when needed.
If, for some reason, you can't do this and you can't use generics, then you have to do it yourself. Pass a Type object to the MyWFCClass constructor, then use reflection to find and invoke the constructor you want.
If you want to pass in a type, you can use the Type object:
public class A
{
public A(Type classType)
{
object myObject = Activator.CreateInstance(...classType...);
}
}
public class B
{
...
}
public class C
{
public static void main(string[] args)
{
A a = new A(typeof(B));
}
}
Far simpler, and more consistent with other applications that have this problem, would be to extract an interface on UserDal, then you would have something more like:
public MyWCFClass() : this(new UserDAL())
{
}
public MyWCFClass(IUserDal userDAL)
{
_myUserDAL = myUserDAL;
}
This is also easier to use with dependency-injection frameworks than your proposed method, though that's certainly a secondary concern
(Edited to clarify an alternative solution based on other comments)
If your DAL is essentially worthless after use because it is mutated, take a constructor with IUserDalFactory instead, with one method Create().
If IUserDAL defines the interface that your WCF service needs to get its job done, why not just take an instance of it as a constructor parameter? And since WCF requires a default constructor, why not have that default constructor call your parameterized constructor with a default implementation?
public class MyWCFClass : IMyWCFClass
{
private readonly IUserDAL _userDAL;
public MyWCFClass()
: this(new DefaultUserDAL())
{
}
public MyWCFClass(IUserDAL userDAL)
{
_userDAL = userDAL;
}
}
If you're using a dependency injection container, you could expose it as a singleton and satisfy the parameterized constructor by using that singleton:
public MyWCFClass()
this(Container.Instance.Resolve<IUserDAL>())
{
}
With this approach, your WCF class has everything it needs to get its job done, but it is still unit-testable. Moreover, it is not responsible for creating its dependencies, which is a good thing.
In C# there is a type called "Type". With it you can create a parameter and pass in any valid type.
private void MyMethod(Type myType)
{
//Do something
}

Categories

Resources