I ran across some code today that is a little confusing to me. I have a class called Operator. Help me understand what is happening in the constructor of the class. I do not understand why it has the UsedImplicity attribute and I do not know what "this(r => { })" is accomplishing.
public class Operator
{
[NotNull] readonly IUnityContainer _container;
[NotNull] readonly ServerWrapper _server;
[UsedImplicitly]
public Operator()
: this(r => { })
{
}
UPDATE - The other constructor:
public Operator([NotNull] Action<IUnityContainer> register)
{
_container = new UnityContainer()
.RegisterType<ISettingsReader, MessageBusSettingsReader>(
new ContainerControlledLifetimeManager())
.RegisterType<IImpersonationStrategyFactory, ImpersonationStrategyFactory>();
register(_container);
_operator= new OperatorWrapper(_container.Resolve<ISettingsReader>());
}
The constructor provides a callback mechanism: On instantiating an Operator, you as the caller may pass in a method pointer (lambda or not) with the Action<IUnityContainer> signature, that would be a void Callback(IUnityContainer c) for example, or a c => { do_something_with_c(c); }.
The default constructor, that is the one without arguments, chains the constructor with an empty method body, it basically ignores (throws away) the container callback. It does so because it needs to execute the initialization code in that second constructor, but cannot call it without its required argument.
Second subquestion: UsedImplicitly is to get rid of warnings when a symbol is never referenced but meant to be used by reflection or called externally, is well documented here.
Related
I have a C# code
private class EvaluationTask : Task<Solution> {
private Problem problem_;
private Solution solution_;
public EvaluationTask(Problem problem, Solution solution)
{
problem_ = problem;
solution_ = solution;
}
}
Now, I am getting error System.Threading.Tasks.Task<> does not contain constructor that takes 0 arguments. From previous answers posted, I found that one has to define empty constructor in the base class. But since my base class is Task<>, how do I add an empty constructor to it?
Any help would be highly appreciated!
Edit: I have to inherit task<> because I have to use the method EvaluationTask in a code:
taskList_ = new List<Task<Solution>>();
taskList_.Add(new MultithreadedEvaluator.EvaluationTask (problem_, solution));
I don't know about task composition, so if it is necessary can anyone help with that? Or if by any way I can avoid inheriting Task and still implement taskList_.Add()?
When you inherit from a class, in your constructors you need to call any of the constructors of the base class. In your case, since you aren't calling any constructor, the compiler try to call a parameterless constructor of the base class, but Task<> haven't a parameterless constructor.
As you can read here, inheriting from Task<> probably isn't a good idea, but you can do something like this:
class EvaluationTask : Task<Evaluation>
{
public EvaluationTask()
: base(DoWork) { }
private static Evaluation DoWork()
{
//...
}
}
When using Task<T>, you must supply the Func<> or Action<> delegate (i.e., function pointer to the desired work to perform) as a constructor argument. It is indeed somewhat unfortunate that there isn't any constructor which lets you bypass this requirement and supply the delegate at a later time (yet obviously still prior to calling Start()), since this severely hampers the ability to extend the Task and Task<TResult> classes via inheritance altogether.
The reason it's a crippling omission is that no delegate you supply as a constructor argument can possibly directly incorporate a reference to the instance you are trying to construct, since that instance (again, obviously) doesn't exist yet, chicken/egg style.
Hence #Arturo's answer, which shows that you can, in fact, supply a static delegate, but since such a delegate has no obvious way of referencing one particular Task instance, it essentially defeats the purpose of inheriting from Task in the first place.
--- reflection disclaimer ---I've been using this technique in my own projects for years on .NET Framework 4.7 (desktop) with no problems whatsoever, but please note that code which uses reflection to access non-public behavior is subject to breakage if the .NET internals change in a later version. You have been warned.
Here's a more flexible workaround for the problem, a general-purpose abstract base class for Task<TResult> which allows you to provide the desired work code in the normal way for derived type hierarchies: as an instance method override. This is a reflection solution; the way it works is to provide a dummy "placeholder" delegate to the base constructor call, but then immediately in the constructor body, swap it out for the "real," desired abstract instance work method, which at that point is no longer unknowable or rather unbindable.
abstract class TaskBase<TResult> : Task<TResult>
{
readonly static FieldInfo m_action =
typeof(Task).GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic);
readonly static Func<TResult> _dummy = () => default;
public TaskBase(CancellationToken ct, TaskCreationOptions opts)
: base(_dummy, ct, opts) =>
m_action.SetValue(this, (Func<TResult>)function);
public TaskBase(CancellationToken ct)
: this(ct, TaskCreationOptions.None)
{ }
public TaskBase(TaskCreationOptions opts)
: this(default, opts)
{ }
public TaskBase()
: this(default, TaskCreationOptions.None)
{ }
protected abstract TResult function(); // <-- override with your work code
};
To use this, simply inherit from TaskBase<TResult>, and override the abstract method function() to implement your task work logic. There is no need for a version of this base class where the work function accepts a AsyncState argument/parameter(s), since you can simply declare all the relevant context for the specific work instance as additional instance fields (and instance methods, and instance properties...) in your derived class. So the constructor variations I declared exactly match those provided by Task<TResult>, but minus the 'function' and 'state' arguments. And finally, don't forget to call Start() when your packaged work instance is ready to go!
The above is a actually a simplified version of the TaskBase<TResult> code I've had much success with. My enhanced version avoids creating the Func<TResult> delegate which must be created for each TaskBase instance in order to "wrap" the C# method function() as an instance delegate. Instead of initially providing a 'dummy' delegate to the base constructor, I always provide (the same) static delegate, a singleton which acts as a "thunk" that universally reinterprets, or "upcasts" a Task<TResult>'s AsyncState object as a pertinent TaskBase<TResult> instance, and then calls function() directly on that instance. Like so:
static Func<Object,TResult> thunk = obj => ((TaskBase<TResult>)obj).function();
So fn_redirect is the only "excess" delegate we need to create once at startup, and this singleton is always passed-in as the base constructor work delegate. Now as with that constructor argument, the "async state" object is also only passed in as a constructor argument and normally cannot later be changed. We don't need a "dummy" in this approach, because you can--and should--pass in 'null' for state. Similar to before we use reflection to set a field, but this time it's m_stateObject field instead of m_action, to replace the 'null' value we just installed for the instance this pointer:
public TaskBase(CancellationToken ct, TaskCreationOptions opts)
: base(thunk, default(Object), ct, opts)
{
m_stateObject.SetValue(this, this);
}
Voila, allocating one extra delegate for each TaskBase instance is avoided. Finally, recall that there are no adverse loss of capability when co-opting the state object for the purpose of this enhancement because as I mentioned earlier, the whole AsyncObject argument-passing mechanism is unnecessary when you entirely control the derived class you are writing.
Here is an inheritable class that inherits from Task<T>, and allows delayed assignment of the task's function. The constructor takes no arguments. The function is assigned by the property Function.
public class FlexibleTask<T> : Task<T>
{
private readonly Helper _helper;
public Func<T> Function { set { _helper.SetFunction(value); } }
public FlexibleTask() : base(GetFunction())
{
this._helper = TempHelper;
TempHelper = null;
}
private static Func<T> GetFunction()
{
Func<T> function = Default;
var helper = new Helper();
helper.SetFunction = f => function = f;
TempHelper = helper;
return () => function();
}
private static readonly Func<T> Default = () =>
throw new InvalidOperationException("Function is not set.");
[ThreadStatic] private static Helper TempHelper;
private class Helper
{
public Action<Func<T>> SetFunction {get; set;}
}
}
Usage Example:
public class EvaluationTask : FlexibleTask<int>
{
}
var task = new EvaluationTask();
task.Function = () => 13;
task.Start();
var result = await task;
Console.WriteLine($"Result: {result}");
Output:
Result: 13
I'm trying to use the AutoMapper for model-viewmodel mapping and wanted to have the mapping configuration executed once in the static constructor of the type. The static constructor of a type is not invoked when Mapper.Map (AutoMapper) is invoked with that type.
My understanding is that the Mapper.Map would try to access the type, its members through reflection and on the first attempt of the usage the static constructor would be called. This is something basic but challenges my understanding. The code snippet is provided.
class SampleViewModel
{
static SampleViewModel()
{
Mapper.Initialize(cfg => cfg.CreateMap<Sample, SampleViewModel>().ReverseMap());
}
public SampleViewModel()
{
}
public int PropertyA { get; set; }
public int PropertyB { get; set; }
}
Sample s = new Sample { PropertyA = 10, PropertyB = 20 };
var obj = Mapper.Map<SampleViewModel>(s); // fails
Isn't the static constructor called (if provided) when the type and members are accessed through reflection for the first time?
You're not accessing any members of SampleViewModel - it's not enough to just reference the type itself.
Mapper.Map only accesses its own internal "dictionary" of mappings - before it could ever get to a point where it deals with a SampleViewModel, it fails. The static constructor never runs, so it cannot add "itself" into the Mapper.
Now, if this didn't involve reflection, you would be right that the static constructor would be called - simply because it would happen during the compilation of the method containing the access, e.g.:
var obj = Mapper.Map<SampleViewModel>(s);
Console.WriteLine(obj.SomeField);
In this case, since the method is referencing a field on SampleViewModel, the static constructor for SampleViewModel will be invoked during JIT compilation of the containing method, and as such, the Mapper.Map<SampleViewModel>(s) line will execute correctly, since the mapping is now present. Needless to say this is not the proper solution to your problem. It would just make the code absolutely horrible to maintain :)
DISCLAIMER: Even though this might fix the problem right now, it depends on a non-contractual behaviour in the current implementation of MS.NET on Windows. The contract specifies that the type initializer is invoked before any access to a member of the type, but that still means that a valid implementation of CIL might only call the type initializer after Mapper.Map, as long as it happens before obj.SomeField - and even then, it might be that obj.SomeField gets optimized away if the compiler can ensure it is safe to do so. The only real way to enforce the call of the type initializer is to call RuntimeHelpers.RunClassConstructor, but by that point, you could just as well add a static Init method or something.
The real problem is that you shouldn't really initialize stuff like this in a static constructor in the first place. Mappings should be set in some kind of deterministic initialization process, say, an explicitly invoked InitMappings method. Otherwise you're opening yourself to a huge can of Heisenbugs, not to mention subtle changes in the CLR breaking your whole application for no apparent reason.
Static constructors just aren't meant for "registration", just the initialization of the type itself - anything else is an abuse, and will cause you (or the .NET compatibility team) trouble.
Static constructors run at an implementation-defined time just before the first instance of that class is created, or before any static member of that type is accessed. See When is a static constructor called in C#?.
The mapper tries to find a mapping before doing its work of instantiating the class to map into, and thus can't find a mapping, because the class was never instantiated before that moment.
Just move your mapping initialization code into a AutoMapperBootstrap.cs file or something, and call that in your application initialization.
".. The static constructor of a type is not invoked when Mapper.Map (AutoMapper) is invoked with that type..."
I tested your scenario and observed that the static constructor is indeed being called before the first instance of the object is created.
C# Programming Guide: Static Constructors
I also went ahead and modified the sample code by adding a GetMapper function which returns an IMapper. This might seem like an overkill for day-to-day simple mapping, but if we need an object to give us its mapper, perhaps we can get it from a static method.
One can easily move the responsibility of creating the Mapper object to a factory or a DI container which, for the sake of simplicity, I did not include here.
Worth noting that in this example, the static fields are initialized before the static constructor which is called right after the static read-only fields are initialized.
Uses AutoMapper v12.0 and .Net Core 3.1.
public class SimpleObjectToMap
{
private static readonly MapperConfiguration _simpleObjMapperConfig = new MapperConfiguration(
config => config.CreateMap<SimpleObjectToMap, ObjectToBeMappedTo>());
private static readonly IMapper _mapper = new Mapper(_simpleObjMapperConfig);
private int _propertyA;
public int PropertyA
{
get
{
Console.WriteLine("ObjectToMap.PropertyA.Get");
return _propertyA;
}
set { _propertyA = value; }
}
static SimpleObjectToMap()
{
Console.WriteLine("*** ObjectToMap static ctor called ***");
}
public static IMapper GetMapper()
{
return _mapper;
}
}
public class ObjectToBeMappedTo
{
static ObjectToBeMappedTo()
{
Console.WriteLine("*** ObjectToBeMappedTo static ctor called ***");
}
private int _propertyA;
public int PropertyA
{
get { return _propertyA; }
set
{
Console.WriteLine("ObjectToBeMappedTo.PropertyA.Set");
_propertyA = value;
}
}
}
public class TestObjectMappingWithStaticCtor
{
public void TestWithStaticCtor()
{
SimpleObjectToMap objToMap = new SimpleObjectToMap { PropertyA = 27 };
var mappedObject = SimpleObjectToMap.GetMapper().Map<ObjectToBeMappedTo>(objToMap);
}
}
I have an abstract factory which creates some service represented by IService interface. In the factory I have two Create methods, because at one of them I allow the consumer to pass an existing IServiceLogger instance to be used by the constructed service tree.
public interface IMyServiceFactory {
IMyService Create(IServiceLogger loggerInstance);
IMyService Create();
}
Because an IServiceLogger should be shared among the service tree, I use the InCallScope when binding it to a concrete implementation.
How can I implement this scenario with Ninject? I've tried the following approaches.
1. Manually create a factory implementation
internal class MyServiceFactory : IMyServiceFactory {
private IResolutionRoot _kernel;
public MyServiceFactory
public IMyService Create(IServiceLogger loggerInstance) {
// what should go here? how can I pass the existing instance to Ninject Get method and make Ninject to use it for the whole resolution tree, just as it were created by Ninject and used as InCallScope?
}
// this one is trivial...
pulbic IMyService Create() {
return _kernel.Get<IMyService>();
}
}
UPDATE
Actually I've found a messy and not too safe way for this. I can get the current bindings via GetBindings, then Rebind IServiceLogger ToConstant, then Get the IMyService instance, and finally restore the original bindings with AddBinding. I don't like it, it feels stinky and what's worse, it's not thread-safe, because another thread can request for a IMyService in the middle of this code and hence use the local temporary binding.
2. Use Ninject.Extensions.Factory
Just use the ToFactory binding, but that's not working, because it just tries to use the parameter as a simple constructor argument (if applicable), and not as an object for the whole resolution tree.
I would give more control to the Kernel of Ninject and do not create a class for the factory at all.
And use Func binding in Ninject like this:
Bind<Func<IMyService>>().ToMethod(s => CreateService);
By binding of the ILoggerService or not binding this you can controll centrally whether you have logger or not in your service.(try by just comment it out)
Here implementation of the Bootstrapper:
public class Bootstrapper
{
private IKernel _kernel = new StandardKernel();
public Bootstrapper()
{
_kernel.Bind<MyStuff>().ToSelf();
_kernel.Bind<IServiceLogger>().To<ServiceLogger>();
_kernel.Bind<IMyService>().To<MyService>();
_kernel.Bind<Func<IMyService>>().ToMethod(s => CreateService);
}
public IKernel Kernel
{
get
{
return _kernel;
}
set
{
_kernel = value;
}
}
private IMyService CreateService()
{
if(_kernel.GetBindings(typeof(IServiceLogger)).Any())
{
return _kernel.Get<IMyService>(new ConstructorArgument("logger", _kernel.Get<IServiceLogger>()));
}
return _kernel.Get<IMyService>();
}
}
Implementation of consumer class for the factory:
internal class MyStuff
{
private readonly Func<IMyService> _myServiceFactory;
public MyStuff(Func<IMyService> myServiceFactory)
{
_myServiceFactory = myServiceFactory;
_myServiceFactory.Invoke();
}
}
Simple implementation of MyService:
internal class MyService
:IMyService
{
public MyService()
{
Console.WriteLine("with no parameters");
}
public MyService(IServiceLogger logger)
{
Console.WriteLine("with logger parameters");
}
}
Simple ServiceLogger:
internal class ServiceLogger
:IServiceLogger
{
public ServiceLogger()
{
}
}
internal interface IServiceLogger
{
}
IMPORTANT UPDATE
While my original answer gave me a working solution, by an accidental InteliSense navigation I've just found that there is a built-in tool for exactly this issue. I just have to use the built-in TypeMatchingArgumentInheritanceInstanceProvider which does this, and even more, because there are no more needs for naming conventions due to the parameter type matching.
It would be good to have a more detailed documentation about these options, or maybe it's just me who can't find it currently.
ORIGINAL ANSWER
I tried a few ways, and ended up with a slightly different, kind of a convention based approach utilizing Ninject's context parameter inheritance.
The convention is used at constructor argument naming through the dependency tree. For example whenever an IServiceLogger instance is injected to a service class, the argument should be called serviceLogger.
With the above convention in mind, I've tested the following approach. Firstly I've implemented a custom instance provider for the factory extension. This custom provider overrides the mechanism for creating constructor parameters for the context to let the developer specify several named arguments which should be set as inherited. This way all the parameters with the specified names will inherit through the whole request graph during the get operation.
public class ParameterInheritingInstanceProvider : StandardInstanceProvider
{
private readonly List<string> _parametersToInherit = new List<string>();
public ParameterInheritingInstanceProvider(params string[] parametersToInherit)
{
_parametersToInherit.AddRange(parametersToInherit);
}
protected override IConstructorArgument[] GetConstructorArguments(MethodInfo methodInfo, object[] arguments)
{
var parameters = methodInfo.GetParameters();
var constructorArgumentArray = new IConstructorArgument[parameters.Length];
for (var i = 0; i < parameters.Length; ++i)
constructorArgumentArray[i] = new ConstructorArgument(parameters[i].Name, arguments[i], _parametersToInherit.Contains(parameters[i].Name));
return constructorArgumentArray;
}
}
Then after at binding configuration I just threw it in with the corresponding parameter name.
kernel.Bind<IMyServiceFactory>().ToFactory(() => new ParameterInheritingInstanceProvider("serviceLogger"));
Finally I reviewed parameter naming, and for exampled changed loggerInstance in the factory interface to serviceLogger to match the convention.
This solution is still not the nicest one as it has several limitations.
It is error prone. One can make bugs which are hard to track by not keeping the naming convention, because currently it silently fails if the convention does not match. This could be improved probably, I'll think about it later.
It handles only constructor injection, however this should not be a big issue as that's the suggested technique. For example I almost never do other kind of injections.
I realise this was asked a long time ago but I was looking to do the same sort of thing myself and finally worked out that you can use the IParameter array passed to the Get() method to specify a ContructorArgument to use only for the current Get() call. This allowed me to use a specific constructor value when creating a Hangfire Job allowing the Hangfire job to use a different database connection on each invocation if required.
EnvironmentName forcedEnv = new EnvironmentName() { Name = dbName };
// For this instantiation, set the 'envName' parameter to be the one we've specified for this job
var instance = ResolutionExtensions.Get((IResolutionRoot) _kernel, jobType,
new IParameter[] {new ConstructorArgument("envName", forcedEnv, true)});
return instance;
By setting the shouldInherit value to true you can ensure the value gets passed down the resolution chain. So it get's passed to any objects in the dependency tree that use that argument (but only for this particular instantiation).
I've noticed in the tutorials for interception that you can target a method and intercept it. I.e.
Kernel.Bind<Foo>().ToSelf();
Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(), invocation => {} );
The documentation/tutorial does not cover what to do in the instance that the method you're trying to intercept has parameters i.e if ThrowsAnError accepted a string as a parameter.
Kernel.Bind<Foo>().ToSelf();
Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(**param goes here**), invocation => {} );
At the time of binding I do not have access to the params so I was wondering whether I am going about this the wrong way?
Edit
Working example
I think you are misunderstanding what happens. Your Foo object is replaced with an decorator that contains the interceptor. Here is a simplistic example:
public class FooDecorator : Foo
{
private readonly Foo decorated;
public FooDecorator(Foo foo) { this.decorated = foo; }
public void ThrowsAnError(object param1, int param2)
{
// calls the decorated instance with supplied parameters
this.decorated.ThrowsAnError(param1, param2);
}
}
In other words, the parameters that are supplied when the resolved Foo is called, will be passed on to the decorated instance.
With interception however, this is all a bit more indirect (and slower), but the concept is the same. I must admit that I'm not familiar with Ninject interception, but there is probably a Proceed method on the invocation object. In other words, you should do something like this:
Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(),
invocation =>
{
try
{
// calls the decorated instance with supplied parameters
invocation.Proceed();
}
catch (Exception ex)
{
Kernel.Get<ILogger>().Log(ex);
}
} );
UPDATE
I assume that the first argument of the InterceptReplace<T> method is not an delegate, but an expression tree, such as Expression<Action<T>>. This method is in fact not called, but it is analyzed to find out which method to intercept. In other words, since the method is never called, you can just supply any argument you which. The trick is to let the C# compiler know which method overload (if any) to use. It doesn't matter if you supply rubbish. When both arguments are reference types, this will probably work:
Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(null, null),
Does structuremap allow you to do constructor injection in a lazy fashion?
Meaning not creating the object which is injected until it is used?
UPDATE: StructureMap v3 implements this out of the box, so this trick is no longer necessary.
StructureMap version 2 doesn't, but with a few tricks you can get it to do what I believe you are looking for. First of all, you can already wire up Lazy<T> instances manually like this:
container = new Container(x =>
{
x.Scan(y =>
{
y.TheCallingAssembly();
y.WithDefaultConventions();
});
x.For<Lazy<IFoo>>().Use(y => new Lazy<IFoo>(y.GetInstance<Foo>));
x.For<Lazy<IBar>>().Use(y => new Lazy<IBar>(y.GetInstance<Bar>));
x.For<Lazy<IBaz>>().Use(y => new Lazy<IBaz>(y.GetInstance<Baz>));
});
This works just fine, but you have to register each and every type individually. It would be nicer if you could take advantage of a more convention-based approach. Ideally, the following syntax would be nice.
x.For(typeof(Lazy<>)).Use(typeof(Lazy<>));
This syntax actually works... somewhat. Unfortunately, at runtime, StructureMap will attempt to find the "greediest" constructor for Lazy<T> and settle on public Lazy(Func<T> valueFactory, bool isThreadSafe). Since we didn't tell it what to do with the boolean isThreadSafe parameter, it will throw an exception when it tries to resolve `Lazy'.
The documentation for Lazy states that the "thread safety mode" of the default Lazy(Func<T> valueFactory) constructor is LazyThreadSafetyMode.ExecutionAndPublication, which just so happens to be what you get by passing true into the isThreadSafe parameter of the constructor above. So, if we could just tell StructureMap to pass true for isThreadSafe, we would get the same behavior as if we called the constructor we actually wanted to use in the first place (e.g. Lazy(Func<T> valueFactory)).
Simply registering x.For(typeof(bool)).Use(y => true) would be very reckless and dangerous since we would be telling StructureMap to go ahead and use the value true for any boolean anywhere. Instead, we need to tell StructureMap what value to use for just this one boolean parameter, which we can do like this.
x.For(typeof(Lazy<>)).Use(typeof(Lazy<>))
.CtorDependency<bool>("isThreadSafe").Is(true);
StructureMap now knows to use the value of "true" for the isThreadSafe parameter when resolving Lazy<T>. We can now use Lazy<T> in constructor parameters, and get the behavior I believe you were looking for.
You can read about the Lazy class in more detail here.
Yes, it does. The latest version of StructureMap (2.6.x) is compiled against .NET Framework 3.5, and so does not have access to the Lazy<T> type introduced in .NET 4. However, it does support the same functionality - "not creating the object which is injected until it is used". Instead of depending on a Lazy<T>, you depend on a Func<T>. No special container registration is required.
I've included a sample program that creates the following output:
Created Consumer
Consuming
Created Helper
Helping
Sample.cs:
class Program
{
static void Main(string[] args)
{
var container = new Container(x =>
{
x.For<IConsumer>().Use<Consumer>();
x.For<IHelper>().Use<Helper>();
});
var consumer = container.GetInstance<IConsumer>();
consumer.Consume();
}
}
public class Consumer : IConsumer
{
private readonly Func<IHelper> _helper;
public Consumer(Func<IHelper> helper)
{
_helper = helper;
Console.WriteLine("Created Consumer");
}
public void Consume()
{
Console.WriteLine("Consuming");
_helper().Help();
}
}
public interface IConsumer
{
void Consume();
}
public interface IHelper
{
void Help();
}
public class Helper : IHelper
{
public Helper()
{
Console.WriteLine("Created Helper");
}
public void Help()
{
Console.WriteLine("Helping");
}
}