Dynamically instantiate objects when they're first invoked in autofac c# - c#

Im trying to figure out how to dynamically instantiate class when it's first used. Something like autofac's Lazy does but without refactoring all my classes.
Is there any possiblity to do something like this:
public class MyService : IMyService {
public MyService() {
// I want it to be invoked only if SomeMethod was invoked before.
// 1. Attempt to invoke SomeMethod
// 2. call MyService.constructor
// 3. invoke MyService.SomeMethod()
}
public void SomeMethod() {
///literally any code.
}
}
It has to be done without changing existing codebase (except services registration/ autofac setup or other areas that could be changed without much effort), and all services look's like that:
public class Service : IService {
public Service(AnotherService service){
///...
}
}
My initial idea was to create Proxy class and then while registering services wrap it with that proxy.
It could look something like this:
public class Proxy<T>
{
private T _target;
private bool instantiated = false;
private void Instantiate()
{
Console.WriteLine("Creating instance");
_target = Activator.CreateInstance<T>();
}
public void xxx() - this method should be called every time any wrapped type method get's called.
{
if (instantiated == false)
{
Instantiate();
instantiated = true;
}
/// proceed with invocation. (im not sure how to do this via reflection).
}
}
The main issue with this idea is that above proxy class should be created at runtime via reflection and it has to mimic wrapping class behaviour.
I'd appreciate any advice on how to approach this problem.
All i want to lazy create dependencies in autofac container (currently if dependency A is requiring dependency B then B is instantiated, i want change this to instantiate B only if any method from A calls B.method).
Thanks!

What you're looking for is the Proxy pattern. You can create a lazy proxy as follows:
public class LazyMyServiceProxy : IMyService
{
private readonly Lazy<MyService> lazy;
public LazyMyServiceProxy(Lazy<MyService> lazy) => this.lazy = lazy;
public void SomeMethod() => this.lazy.SomeMethod();
}
You can use this proxy using the following Autofac registrations.
builder.RegisterType<MyService>();
builder.RegisterType<LazyMyServiceProxy>().As<IMyService>();

Related

call an instance method from static method? (how to get dependency injection to work in a console app)

I have the following ISampleInterface interface
public interface ISampleInterface
{
bool sampleMethod(string _txt);
}
So that interface I implemented like this,
public Class SampleInterface : BaseEntity<Sample>, ISampleInterface
{
IContext _context;
public SampleInterface (IContext context)
: base(context)
{
_context = context;
}
public bool sampleMethod(string _txt)
{
return true;
}
}
so from my main static method how to call this sampleMethod, without invoking SampleInterface class
my Service class tight to an entity, which is "Sample", so I just want to know, without invoke Service class, can call this method(sampleMethod) via ISampleInterface
public static void main(String[] args)
{
}
Exact issue I’m facing, I have batchjob and web project, web project i can invoke this method via IOC addictive, also i want to invoke same method in batchjob, i cant it’s because of batchjob’s main method is static method
sampleMethod is an instance method, so you need an instance. There is no way to call it without one!
public static void main(String[] args)
{
var instance = new SampleInterface();
instance.sampleMethod("some text");
}
Calling an instance method without any instance has no meaning in C#.
It's like asking to do numeric calculation without number.
Maybe related to your context: interfaces must be implemented at the instance level, there are no such thing as static interfaces. While not completely impossible to achieve, this is not available in C#, by design.
So, with instances, for completeness of answer:
To create an instance, use a constructor (since you didn't defined any constructor, a default public parameterless constructor is created implicitly)
Then, you can call the method on the instance.
var instance = new SampleInterface();
instance.someMethod("foo");

Using the parent object in OnActivation() as an argument

I have a component I am injecting with Ninject, and it has a member function that must be called after it is instantiated. I didn't put it in the constructor because it requires a reference to it's parent object and that would create a circular reference.
Currently, I just call the method in the parent's constructor, but it would be cleaner and less likely to be forgotten if I could have Ninject run the method for me.
Due to a lack of documentation, I have been fiddling with OnActivation, but can't seem to get it working.
Basically what I would like to do is:
Bind<IMessageService>().To<QueuedMessageService>().InSingletonScope()
.OnActivation((ctx, svc) => { svc.SubscribeAll(ctx.Request.Target); });
where SubscribeAll(object target)
AM I even on the right path or am I way out in left field? Thanks!
You can use IInitializable interface:
public class Parent : Ninject.IInitializable
{
private readonly IMessageService service;
public Parent(IMessageService service)
{
this.service = service;
}
public void Initialize()
{
service.SubscribeAll(this);
}
}
Initialize method will be called automatically by ninject.

Need to create fakes for a class that manipulates the results of interface in microsoft unit testing tool using c#

I need to implement fakes for unit testing one of my methods. Problem is the method I need to test calls a class method and retrieves some system parameters.Scenario is as below:
Class A(){
public void method xx(){
//This needs to be tested.
//This method makes a call to retrieve some informations. The call is like
below:
String culture=Api.GetEnvironmentData().GetCulture();
//This is the problem area.
boolean implmentApi=Api.GetEnvironmentData().DoImplmentApi();
//This is the problem area.
}
}
This GetEnvironmentData method is something like this:
public static EnvironmentData GetEnvironmentData ()
{
return GetDiContainer().Resolve<EnvironmentData >();
}
EnvironmentData class is something like this:
public class EnvironmentData(){
public EnvironmentData(IEnvironmentDataProvider EnvironmentDataProvider){
//
}
}
I can fake the IEnvironmentDataProvider using moq but am not able to figure out how to fake the EnvironmentData class. I need to fake the EnvironmentData class because it manipulated the results of IEnvironmentDataProvider based of various method calls. For example both GetCulture and DoImplmentApi call the getData method of the interface IEnvironmentDataProvider and then cast them accordingly.
Now when I fake the IEnvironmentDataProvider and return some value I am not able to control what to return when GetCulture and when DoImplmentApi is called.
Can some one suggest how to implement the fakes for the above scenario.
You don't need to mock dependencies of EnvironmentData class. I see one problem here: you are using DI container, like Service Locator, which in this scenario behave like antipattern. All dependencies should be injected, e. g.: by constructor or property.
Change your Api class to something like this:
public class Api
{
private readonly EnvironmentData _environmentData;
public Api(EnvironmentData envData)
{
environmentData = envData;
}
public string GetCulture()
{
return _envData.GetCulture();
}
}
Remember that implementation details of Api class should be hidden. You shouldn't expose EnvironmentData in this scenario. Api class should ask for all dependencies which are needed to implement this class and has own interface.
Based on your comments, I think your best shot is to wrap the static class in a facade. Then you can mock the facade.
Something like this:
Class A
{
IEnvironmentDataFacade _environmentDataFacade;
Class A(IEnvironmentDataFacade environmentDataFacade)
{
_environmentDataFacade = environmentDataFacade;
}
public void method xx()
{
//Now you can fake IEnvironmentDataFacade:
String culture= _environmentDataFacade.GetCulture();
//Do the same as above with the method here:
boolean implmentApi=Api.GetEnvironmentData().DoImplmentApi();
//This is the problem area.
}
}
public class EnvironmentDataFacade : IEnvironmentDataFacade
{
public string GetCulture()
{
return Api.GetEnvironmentData().GetCulture();
}
}
public interface IEnvironmentDataFacade
{
string GetCulture();
}

IoC, Dependency injection and constructor arguments

I have a service that I want to be able to create according to the Inversion of Control principle so I have created an interface and a service class.
public interface IMyService
{
void DoSomeThing1();
void DoSomeThing2();
void DoSomeThing3();
string GetSomething();
}
public class MyService : IMyService
{
int _initialValue;
//...
public MyService(int initialValue)
{
_initialValue = initialValue;
}
public void DoSomeThing1()
{
//Do something with _initialValue
//...
}
public void DoSomeThing2()
{
//Do something with _initialValue
//...
}
public void DoSomeThing3()
{
//Do something with _initialValue
//...
}
public string GetSomething()
{
//Get something with _initialValue
//...
}
}
With for example Unity I can set up my IoC.
public static class MyServiceIoc
{
public static readonly IUnityContainer Container;
static ServiceIoc()
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IMyService, MyService>();
Container = container;
}
}
The problem is the constructor parameter. I could use a ParameterOverride like
var service = MyServiceIoc.Container.Resolve<IMyService>(new ParameterOverrides
{
{"initialValue", 42}
});
But I don't want to use losely typed parameters. What if someone changes the constructor parameter name or adds one parameter? He won't be warned at comple-time and maybe no one will detect it but the end user. Maybe the programmer changes he IoC setup for the tests, but forgets it for the "release" usage, then not even a codebase with 100% code coverage will detect the run-time error.
One could add an Init-function to the interface and service, but then the user of the service have to understand that and remember to call the init function every time he gets an instance of the service. The service becomes less self explanetory and open for incorrect usage. I'ts best if methods are not dependent on which order they are called.
One way to make it a little safer would be to have a Create-function on the Ioc.
public static class MyServiceIoc
{
//...
public IMyService CreateService(int initialValue)
{
var service = Container.Resolve<IMyService>();
service.Init(initialValue);
}
}
But the concerns mentioned above still applies if you only look at the service and its interface.
Does anyone have an robust solution to this problem? How can I pass an initial value to my service in a safe way still using IoC?
A DI Container is reflection-based, and fundamentally weakly typed. The problem is much broader than with Primitive Dependencies - it's present everywhere.
As soon as you do something like the following, you've already lost compile-time safety:
IUnityContainer container = new UnityContainer();
container.RegisterType<IMyService, MyService>();
var service = container.Resolve<IMyService>(new ParameterOverrides
{
{"initialValue", 42}
});
The problem is that you can remove the second statement, and the code still compiles, but now it'll no longer work:
IUnityContainer container = new UnityContainer();
var service = container.Resolve<IMyService>(new ParameterOverrides
{
{"initialValue", 42}
});
Notice that the lack of compile-time safety has nothing to do with the Concrete Dependency, but with the fact that a DI Container is involved.
This isn't a Unity problem either; it applies to all DI Containers.
There are cases where a DI Container may make sense, but in most cases, Pure DI is a simpler and safer alternative:
IMyService service = new MyService(42);
Here, you'll get a compiler error if someone else changes the API while you're looking away. That's good: compiler errors give you more immediate feedback than run-time errors.
As an aside, when you pass in a Primitive Dependency and invisibly turn it into a Concrete Dependency, you make it more difficult for the client to understand what's going on.
I'd recommend designing it like this instead:
public class MyService : IMyService
{
AnotherClass _anotherObject;
// ...
public MyService(AnotherClass anotherObject)
{
_anotherObject = anotherObject;
}
// ...
}
This is still easy and type-safe to compose with Pure DI:
IMyService service = new MyService(new AnotherClass(42));
How can I pass an initial value to my service in a safe way still using IoC?
You can explicitly call a type's constructor while registering it in Unity using the IUnityContainer.RegisterInstance method:
container.RegisterInstance<IMyService>(new MyService(42));
This would give you the compile-time safety that you mention, but the cost is that it would be instantiated only once, and would be created immediately (as opposed to when it is first requested).
You could perhaps deal with this drawback by using one of the method overloads, which accepts a LifetimeManager class.
It depends on your use case, but in IoC container world it could look something like this:
public class MyService : IMyService
{
int _initialValue;
// ...
public MyService(IConfigurationService configurationService)
{
_initialValue = configurationService.GetInitialValueForMyService();
}
// ...
}
If your class with constructor parameters is outside your code (e.g. in 3rd party library), you can use an adapter.
public class AdaptedMyService : MyService
{
public AdaptedMyService(IConfigurationService configurationService)
: base(configurationService.GetInitialValueForMyService())
{
}
}
And then register adapted class in IoC container like this:
container.Register<IMyService, AdaptedMyService>();

Is Service Locator an anti pattern in a pluggable architecture?

I know this question might look like it's a duplicate but please let me explain.
So I created several components that use a pluggable architecture, basically I can freely add new implementations and they will be injected and processed automatically for me. This is really handy in several scenarios.
I'm going to talk about the simplest one, validating components.
One of the reasons to use a design like this is that I like to expose my roles explicitly as explained by Udi Dahan
Basically I have code like this:
public interface IValidatorRuner
{
void Run<TTarget>(TTarget target);
}
public class ValidatorRunenr : IValidatorRuner
{
private readonly IServiceLocator _serviceLocator;
public ValidatorRunenr(IServiceLocator serviceLocator)
{
_serviceLocator = serviceLocator;
}
public void Run<TTarget>(TTarget target)
{
// this is the dynamic/pluggable phase
// is this an antipattern???
var foundValdiators = _serviceLocator.GetAllInstances<IValidator<TTarget>>();
foreach (var valdiator in foundValdiators)
{
valdiator.IsSatisfiedBy(target);
}
}
}
This code lets me expose my validation rules explicitly like this:
//this will allow me to create validators in this way
//and they will be automatically injected and resolved for me
//(easy, to read, easy to write, easy to test, pff I could even smoke this validator easily)
public class OneValdiationRuleExplicitlyExposedAndEasyToTest : IValidator<Person>
{
public bool IsSatisfiedBy(Person target)
{
return target.Age > 18;
}
}
public class Person
{
public int Age { get; set; }
}
public interface IValidator<TTarget>
{
bool IsSatisfiedBy(TTarget target);
}
And I will use this code like this:
//usage
public class SomeCommandHandler
{
private readonly IValidatorRuner _validatorRuner;
public SomeCommandHandler(IValidatorRuner validatorRuner)
{
_validatorRuner = validatorRuner;
}
public void SomeMethod()
{
_validatorRuner.Run(new Person{Age = 16});
}
}
Validation was just one example, I also use it to fire domain events and to run pipelines and filters in the same pluggable way
Is using the service locator in this way an anti-pattern?
I know I might be hiding some dependencies, but the thing is that the dependencies are dynamically injected and discovered when the application initializes (Composition root)
Your thoughts will be greatly appreciated
In my opinion, the primary issue with your code sample is that the service locator is itself injected into the implementation of ValidatorRunner. For me, this is an anti-pattern, but perhaps not the one you're asking about.
Any answer I might give boils down to the capabilities of your service locator implementation. But for sure it should not be passed into the constructor of your class. Instead, the service locator should itself pass these things in when you ask it for an implementation of "IValidatorRuner"
As an example, you can inject a factory that knows how to load the dynamic validator instances for a given type.
If anyone is interested, I found a way to remove the ServiceLocator in my objects and still dynamically load/discover dependencies at run time.
The way I solved it was by registering my components in my DI container in the following way (using the Mediator pattern):
Binding mediator (shortbus) with/to ninject
var kernel = new StandardKernel();
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses()
.InheritedFromAny(
new[]
{
typeof(IValidatorRunner<>)
})
.BindDefaultInterfaces());
And my final implementation looks like:
public interface IValidatorRuner<in TTarget>
{
void Run(TTarget target);
}
public class ValidatorRunenr<TTarget> : IValidatorRuner<TTarget>
{
private readonly IEnumerable<IValidator<TTarget>> _validators;
public ValidatorRunenr(IEnumerable<IValidator<TTarget>> validators)
{
_validators = validators;
}
public void Run(TTarget target)
{
foreach (var valdiator in _validators)
{
valdiator.IsSatisfiedBy(target);
}
}
}
Usage
//usage
public class SomeCommandHandler
{
private readonly IValidatorRuner<OneValdiationRuleExplicitlyExposedAndEasyToTest> _validatorRuner;
public SomeCommandHandler(IValidatorRuner<OneValdiationRuleExplicitlyExposedAndEasyToTest> validatorRuner)
{
_validatorRuner = validatorRuner;
}
public void SomeMethod()
{
_validatorRuner.Run(new Person{Age = 16});
}
}
In few words, by registering an opened generic type, my container resolves any call to that type creating a concrete-closed-generic-type instance at runtime for me.
As you can see in the usage, I do not have to create a specific concrete-closed-generic type of IValidatorRunner<OneValdiationRuleExplicitlyExposedAndEasyToTest> because the container creates one for me.
And there you go, now I'm happy because I removed the service locator from my domain objects =)

Categories