How to create objects using a static factory method? - c#

I know Unity can be configured to use a class' constructor to create an instance of a class (like below) but that's not what I want.
container.RegisterType<IAuthoringRepository, AuthoringRepository>();
I would like to configure Unity to use a factory method with the windows identity passed as a parameter (ie: RepositoryFactory.CreateAuthoringRepository(WindowsIdentity.GetCurrent())) when resolving a type of IAuthoringRepository. How do i do this?

One way is to have RepositoryFactory implement IRepositoryFactory, then register that. Resolved types can get a factory, then call its CreateAuthoringRepository method. You could create an overload called CreateAuthoringRepositoryForCurrentIdentity if desired, or register an IIdentity dependency of the factory with Unity.
I'd probably just inject a factory and leave the CreateAuthoringRepository method as you have it, then have the clients pass WindowsIdentity.GetCurrent(). That way the identity is always fresh, and you can mock the factory for testing.
Alternately, you can specify a delegate with InjectionFactory:
void Main()
{
using (var container = new UnityContainer())
{
container.RegisterType<IAuthoringRepository>(
new InjectionFactory(c => CreateAuthoringRepository()));
Console.WriteLine("debug - resolving model");
var model = container.Resolve<Model>();
}
}
public IAuthoringRepository CreateAuthoringRepository()
{
Console.WriteLine("debug - calling factory");
return new AuthoringRepository
{ Identity = WindowsIdentity.GetCurrent() };
}
public class Model
{
public Model(IAuthoringRepository repository)
{
Console.WriteLine(
"Constructing model with repository identity of "
+ repository.Identity);
}
}
public interface IAuthoringRepository
{
IIdentity Identity { get; }
}
public class AuthoringRepository : IAuthoringRepository
{
public IIdentity Identity { get; set; }
}
This prints:
debug - resolving model
debug - calling factory
Constructing model with repository identity of System.Security.Principal.WindowsIdentity
That's for Unity 2.0. With earlier versions, see StaticFactoryExtension.

Now method InjectionFactory is obsolete. That's why it'd be better to use method RegisterFactory. Below I am showing how the previous code changed. How you see I changed the method CreateAuthoringRepository. Now it is the static method with one param IUnityContainer container
void Main()
{
using (var container = new UnityContainer())
{
container.RegisterFactory<IAuthoringRepository>(CreateAuthoringRepository);
Console.WriteLine("debug - resolving model");
var model = container.Resolve<Model>();
}
}
public static IAuthoringRepository CreateAuthoringRepository(IUnityContainer container)
{
Console.WriteLine("debug - calling factory");
return new AuthoringRepository
{ Identity = WindowsIdentity.GetCurrent() };
}
public class Model
{
public Model(IAuthoringRepository repository)
{
Console.WriteLine(
"Constructing model with repository identity of "
+ repository.Identity);
}
}
public interface IAuthoringRepository
{
IIdentity Identity { get; }
}
public class AuthoringRepository : IAuthoringRepository
{
public IIdentity Identity { get; set; }
}

Related

How to implement Factory for production code, dependency injection for Unit Tests

I want to give a caller of my class ability to choose provider by name, instead of passing the provider concrete class as standard DI recommends. It will allow to hide actual implementation details from client, still giving control which provider to use. We've done it by implementing factory
public ICurrencyProvider GetCurrencyServiceProvider(string providerName)
{
switch (providerName)
{
case "CurrencyLayerAPI":
{ currencyService = new CurrencyLayerWrapper(); }
break;
case "XE":
{ currencyProvider = new XEWrapper(); }
break;
}
return _currencyProvider;
}
and constuctor expects providerName as a parameter.
However for unit tests I wish to use Substitute, not concrete class of provider.
I ended up with 2 parameters, responsible for the same choice- name for production code and interface for calls from tests.
public CurrencyProcessor(string providerName, ICurrencyProvider substituteCurrencyProvider =null)
{
if(!providerName .IsNullOrEmpty())
{
_currencyProvider = GetCurrencyServiceProvider(providerName);
}
else
{ _currencyProvider =substituteCurrencyProvider;
}
}
Slightly alternative implementation is to read providerName from configuration instead of passing it as a parameter.
public CurrencyProcessor(IConfigurationProvider configurationProvider, ICurrencyProvider substituteCurrencyProvider =null)
{
_providerName = _configurationProvider.GetAppSetting("CurrencyProviderToUse");
if(!providerName .IsNullOrEmpty())
{
_currencyProvider = GetCurrencyServiceProvider(providerName);
}
else
{ _currencyProvider =substituteCurrencyProvider;
}
}
I wander, is any better way exist to have single parameter to control creation of internal object, but avoiding giving responsibility to create object to a client.
Related discussions
How to use Dependency Injection without breaking encapsulation?
Preferable way of making code testable: Dependency injection vs encapsulation
https://softwareengineering.stackexchange.com/questions/344442/dependency-injection-with-default-construction
since in your constructor your are statically creating your provider, just inject the provider.
create a factory as you describe....
public class CurrencyFactory
{
public static ICurrencyProvider GetCurrencyServiceProvider(string providerName)
{
return null;
}
}
then use standard dependency injection :-
public class CurrencyProcessor
{
private ICurrencyProvider _currencyProvider;
public CurrencyProcessor(ICurrencyProvider currencyProvider)
{
_currencyProvider = currencyProvider;
}
}
and then use like so
var p = new CurrencyProcessor(CurrencyFactory.GetCurrencyServiceProvider("bitcoin"));
then in your test mock it
var mock = new Mock<ICurrencyProvider>(). // mock stuff
Not sure if I understand it correct.
For me it sounds like you want to have 2 different Factories.
First create a Interface:
public interface ICurrencyProviderFactory
{
ICurrencyProvider Create()
}
Then create a Configuration Factory:
public class ConfigurationCurrencyProviderFactory : ICurrencyProviderFactory
{
public ConfigurationCurrencyProviderFactory(IConfigurationProvider configuration)
{
}
public ICurrencyProvider Create()
{
}
}
And then a UnitTest Factory:
public class UnitTestCurrencyProviderFactory : ICurrencyProviderFactory
{
public UnitTestCurrencyProviderFactory()
{
}
public ICurrencyProvider Create()
{
}
}
Your currency processor should look like this:
public CurrencyProcessor(ICurrencyProviderFactory factory)
{
_currencyProvider = factory.Create();
}
In your ServiceCollection or whereever you resolve your dependencies you should include the correct factory.
So for Production, you add the ConfigurationCurrencyProviderFactory, for UnitTest the UnitTestCurrencyProviderFactory. Your actual code then should depend on ICurrencyProviderFactory.
What you actually need to apply along with your factory is the Strategy Pattern
interface ICurrencyProvider {
//...members
}
public interface ICurrencyProviderStrategy {
string Name { get; }
ICurrencyProvider Create();
}
public interface ICurrencyProviderFactory {
ICurrencyProvider GetCurrencyServiceProvider(string providerName);
}
An implementation of the factory would depend on a collection of strategies to call upon to create the desired types.
public class CurrencyProviderFactory : ICurrencyProviderFactory {
private readonly IEnumerable<ICurrencyProviderStrategy> strategies;
public CurrencyProviderFactory(IEnumerable<ICurrencyProviderStrategy> strategies) {
this.strategies = strategies;
}
public ICurrencyProvider GetCurrencyServiceProvider(string providerName) {
var provider = strategies.FirstOrDefault(p => p.Name == providerName);
if (provider != null)
return provider.Create();
return null;
}
}
This would allow greater flexibility as any number of strategies can be injected.
Here is an example of a CurrencyLayerWrapper Strategy
public class CurrencyLayerWrapperProvider : ICurrencyProviderStrategy {
public string Name { get { return "CurrencyLayerAPI"; } }
public ICurrencyProvider Create() {
return new CurrencyLayerWrapper();
}
}

Registration confusion with autofac and console app

I'm trying to use autofac for dependency injection in my console app. I'm running into issues where autofac can't find constructors for certain interfaces/classes.
Here is my latest example:
IRepository:
public interface IRepository<Planetary>
{
IEnumerable<Planetary> Get();
}
IPlanetaryRepository:
public interface IPlanetaryRepository : IRepository<Planetary>
{
IQueryable<Planetary> GetPlanetary(SystemProbe user);
}
PlanetaryService:
public interface IPlanetaryService
{
Task<Planetary> Clone(Planetary source);
}
public sealed class PlanetaryService : IPlanetaryService
{
private IPlanetaryRepository Repo { get; }
public PlanetaryService(IPlanetaryRepository repo)
{
Repo = repo;
}
}
Scheduler:
public class Scheduler
{
private static IContainer Container { get; set; }
static void Main()
{
var builder = new ContainerBuilder();
builder.RegisterType<PlanetaryService>().As<PlanetaryService>();
builder.RegisterType<IPlanetaryRepository>().As<IPlanetaryRepository>();
Container = builder.Build();
GenerateSchedules();
}
public static void GenerateSchedules()
{
using (var scope = Container.BeginLifetimeScope())
{
var repo = scope.Resolve<PlanetaryService>(); <-- line where exception is thrown
}
}
}
No constructors on type 'IPlanetaryRepository' can be found with the
constructor finder
'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'.
If I take out IPlanetaryRepository, I get this exception:
Cannot resolve parameter IPlanetaryRepository repo of constructor...
So I'm not really sure what to do. 'PlanetaryService' needs 'IPlanetaryRepository' as a parameter, but IPlanetaryRepository doesn't have a constructor.
Is there a way to rectify this?
You don'y have any classes that implement IPlanetaryRepository so it can't find the constructor.

Resolve object using DI container with object instance

I have a ICommand interface and tasks that are using dependencies injected by constructor. Dependencies are using different constructors so they have to be resolved by the request itself. I want to tell my container how to resolve some dependencies in the specific context it's being resolved.
interface ICommand
{
string Do();
}
interface IUser
{
string Name { get; }
}
class Welcome : ICommand
{
IUser _user;
public Welcome(IUser user)
{
_user = user;
}
public string Do()
{
return "Hello, "+_user.Name;
}
}
class OAuthUser : IUser
{
// use remote service to get data
public OAuthUser (IOAuthService service, JsonWebToken token)
{
// to be implemented
}
}
class TemporaryTokenUser : IUser
{
// use sql to check if user has temporary token
public TemporaryTokenUser (IDbConnection db, string token)
{
// to be implemented
}
}
class UserPasswordUser : IUser
{
// try authenticating user with credentials
public UserPasswordUser (IAuthService svc, string user, string password)
{
// to be implemented
}
}
I've registered my interfaces and classes in LightInject:
var container = new LightInject.ServiceContainer();
container.Register<ICommand, Welcome>("welcome");
Now, I want to do something like this in my requests:
using (var scope = container.BeginScope())
{
// I need to tell my container how to resolve this dependency in case its needed
// but method below does not exist
scope.ResolverForScope<IUser>(()=>createIUser(request));
var command = container.GetInstance<ICommand>(command);
return command.Do();
}
What would be the correct way to do this in maintainable way with any DI container, considering that dependency chain might get quite long for complex methods?
EDIT
I made my use case more clear (changed classes implementing IUser).
static class ScopedContainerExtensions
{
class ScopedContainer
{
Dictionary<Type, object> factories = new Dictionary<Type,object>();
public void Register<T>(Func<T> factory)
where T: class
{
factories.Add(typeof(T), new Lazy<T>(factory));
}
public T Resolve<T>()
{
return ((Lazy<T>)factories[typeof(T)]).Value;
}
}
public static void UseScopedContainerFor<Service>(this IServiceContainer container)
{
if (!container.CanGetInstance(typeof(ScopedContainer), ""))
{
container.Register<ScopedContainer>(new PerScopeLifetime());
}
container.Register<Service>(sf=>sf.GetInstance<ScopedContainer>().Resolve<Service>());
}
public static void ResolverForCurrentScope<T>(this IServiceContainer container, Func<IServiceFactory, T> factory)
where T : class
{
var scope = container.ScopeManagerProvider.GetScopeManager().CurrentScope;
container.GetInstance<ScopedStorage>().Register<T>(() =>
{
var instance = factory(container);
var disposable = instance as IDisposable;
if (disposable != null)
scope.TrackInstance(disposable);
return instance;
});
}
Registration:
container.UseScopedContainerFor<IUser>();
Usage in scope:
container.ResolverForCurrentScope<IUser>(fac => fac.GetInstance<OAuthUserFactory>().Create(fac.GetInstance<IOAuthService>(), Request));
It might be developed via using the Factory pattern.
With this approach, you might be able to get an instance of the specific user with a Factory to provide instances for each concrete class.
Using explicit service registration:
var container = new LightInject.ServiceContainer();
//register your command passing a user instance
container.Register<ICommand>(factory => new Welcome(factory.GetUser<IUser>(request)));
using (var scope = container.BeginScope())
{
var command = (ICommand)container.GetInstance<ICommand>();
return command.Do();
}
I just referred to LightInject web page. There is a chapter called "Dependency Constructors" for further information. http://www.lightinject.net/#toc16
Hope it helps

How to inject something in custom validator?

I'm using CustomValidation for one entity and I want to inject Repository in it. Validation method must be static. Is there any way to inject object in static context other than service location?
Here's my metadata:
[MetadataTypeAttribute(typeof(BillPosition.BillPositionsMetadata))]
[CustomValidation(typeof(BillPositionValidator), "ValidateBillPositionsCount")]
public partial class BillPosition
{
internal sealed class BillPositionsMetadata
{
private BillPositionsMetadata() { }
public int BillId { get; set; }
}
}
Here's validator code:
public class BillValidator
{
[Inject]
public static IRepository Repository { get; set; }
public static ValidationResult ValidateBillPositionsCount(BillPosition bill, ValidationContext context)
{
ValidationResult result = ValidationResult.Success;
/* Repository wasn't injected and I get null reference exception */
var billPositions = Repository.BillPositions.Count(position => position.BillId == bill.BillId);
if (bill.BillPositions.Count == 0 && billPositions == 0)
{
result = new ValidationResult("Invalid positions count", new[] { "BillPositions" });
}
return result;
}
}
There is not any way to inject into custom validators. A Service Locator or some form of reflection could be used to either access a property or method on the instance the validator is being executed on. You can access this instance through the ValidationContext.
http://www.jaltiere.com/index.php/2010/05/04/ninject-with-mvc-and-validationattributes/
You can just call the IoC and resolve the dependency. Like I am using Unity. In these cases I would call Bootstrapper.Unity.Resolve("NameOfMyDependency")
If you are not resolving the validator from the dependency injection container, you can still resolve the repository directly using some kind of service locator:
public class BillValidator
{
static BillValidator()
{
Repository = ServiceLocator.Current.GetInstance<IRepository>();
}
public static IRepository Repository { get; set; }
}
That way you can initialize the validator using the new-keyword:
var validator = new BillValidator();
and you still get the dependency resolved in the validator.
Due to the fact that the repository gets resolve in the type initializer it will be executed only once per type in your applcation. All instances of the validator will use the same repository.
This code works when working with Unity, but should be equivalent when working with MEF or other containers.

Unity (dependency injection): How to pass in a parameter to the constructor in RegisterType

Can anyone help?
I have a wpf app (shouldn't matter) and in the Onstart i have my bootstrap stuff.. Its like this..
// Create unity container my service and repository
container = new UnityContainer()
.RegisterType<ISecurityRepository, SecurityRepository>()
.RegisterType<ISecurityService, SecurityService>();
Basically ISecurityService expects me to pass in a ISecurityRepository, hence the above fails.
But i am little confused, do i have to create a new IsecurityRespository and then pass it in, this defeats the object doesn't it?
Is there anyway i say "pass into SecurityService the ISecurityRepository from the container", but it hasn't been built yet?
Any ideas?
You don't have to create instances first. It all just works. That's the magic of IoC Containers.
Example:
public interface ISecurityService { }
public interface ISecurityRepository { }
public class SecurityService : ISecurityService
{
public SecurityService(ISecurityRepository repository)
{
Console.WriteLine("SecurityService created");
Console.WriteLine("Repository is " + repository);
}
public override string ToString()
{
return "A SecurityService";
}
}
public class SecurityRepository : ISecurityRepository
{
public SecurityRepository()
{
Console.WriteLine("SecurityRepository created");
}
public override string ToString()
{
return "A SecurityRepository";
}
}
public class MyClassThatNeedsSecurity
{
public MyClassThatNeedsSecurity(ISecurityService security)
{
Console.WriteLine("My class has security: " + security);
}
}
class Program
{
static void Main()
{
using (IUnityContainer container = new UnityContainer())
{
container.RegisterType<ISecurityRepository, SecurityRepository>()
.RegisterType<ISecurityService, SecurityService>();
MyClassThatNeedsSecurity myClass =
container.Resolve<MyClassThatNeedsSecurity>();
}
}
}
This will print:
SecurityRepository created
SecurityService created
Repository is A SecurityRepository
My class has security: A SecurityService
You have a number of options, such as pre-creating your instances (as you showed in your follow-up post) or extending the lifetime of injected dependencies so that they're not recreated every time they're needed. But for the base case, this will work.
here is some more information. The constructor of my class is
public SecurityService(ISecurityRepository repository)
: base(repository)
{
}
After playing around a little bit, i managed to do the following but this causes me to create instances FIRST ... It seems to work.., but its an alternative.
// Create unity container my service and repository
ISecurityRepository securityRepository = new SecurityRepository();
ISecurityService securityService = new SecurityService(securityRepository);
container = new UnityContainer();
container.RegisterInstance<ISecurityRepository>(securityRepository);
container.RegisterInstance<ISecurityService>(securityService);

Categories