Using Funcs instead of instances in frameworks - c#

When looking at the source code of a couple of projects I found a pattern I can not quite understand.
For instance in FubuMVC and Common Service Locator a Func is used when a static provider is changed.
Can anyone explain what the benefit is of using:
private static Func<IServiceLocator> currentProvider;
public static IServiceLocator Current
{
get { return currentProvider(); }
}
public static void SetLocatorProvider(Func<IServiceLocator> newProvider)
{
currentProvider = newProvider;
}
instead of:
private static IServiceLocator current;
public static IServiceLocator Current
{
get { return current; }
}
public static void SetLocator(IServiceLocator newInstance)
{
current = newInstance;
}

The major advantage of the first model over the second is what's called "lazy initialization". In the second example, as soon as SetLocator is called, you must have an IServiceLocator instance loaded in memory and ready to go. If such instances are expensive to create, and/or created along with a bunch of other objects at once (like on app startup), it's a good idea to try to delay actual creation of the object to reduce noticeable delays to the user. Also, if the dependency may not be used by the dependent class (say it's only needed for certain operations, and the class can do other things that don't require the dependency), it would be a waste to instantiate one.
The solution is to provide a "factory method" instead of an actual instance. When the instance is actually needed, the factory method is called, and the instance is created at the last possible moment before it's used. This reduces front-end loading times and avoids creating unneeded dependencies.

Good answer by #KeithS. Another thing to note here is what happens under the covers of the initialization of certain instances. Keeping a reference to intentionally volatile objects can be tricky.
FubuMVC, for instance, spins up a nested StructureMap container per HTTP request which scopes all service location to that specific request. If you have classes running within that pipeline that have been built up, you'll want to use the contextual injection provided to you via THAT instance of IServiceLocator.

Theres a lot more flexibility to the implementer of newProvider. They can lazy load, async load (and and then if it's not loaded by the time the func is called it can have code to wait), they can allow it change based on runtime parameters etc.

A func allows several things
The locator creation can be delayed until it is needed. It is therefore lazy.
The provider object does not contain any state. It is not its responsiblity to shut down the locator does anything with it except to return the current locator when needed.
When the locator is reconfigured at run time or it decides that a different instance is needed it can control the lifetime of the locator as long as the calling code does not store a reference to locator.
Since the locator is returned by a method it has more flexibility e.g. to create a thread local locator so it can create many objects in each thread without the need to coordinate object creation in one global object which could become a bottleneck when many threads are involved.
I am sure the designers did could give you more points than I did why it can be a good idea to abstract away "simple" things like to return an instance of a service locator.
Yours,
Alois Kraus

Related

Is there a way to force a method to inherit a scope from it's caller?

If I have a method outside it's callers scope that does a few things, and I have to call this method multiple times in multiple places. Is there any way to make the entire scope of the caller available to the method without passing parameters and also without using global variables? Like if I need it to have an access to a List, an entity framework context
Instead of
myMethod(string _string, List<string> _stringList, EntityContext _db)
{
//log _string to a database table
//add _string to _stringList
//etc.
}
Is there a way I can just pass the _string and make the method inherit the scope as if I'm just writing the same three lines of code everywhere I call this method? It seems a lot cleaner to call myMethod("foo") than myMethod("foo", stringList, MyEntities).
I could create a class, instantiate it, and call the class, but I'm just plain curious if scope inheritance or scope passing is a thing.
Absolutely don't do that. If you have a context you need to pass, use a class to represent the context needed, but don't try to handwave it away and hide it. It makes for unmaintainable code full of interdependencies.
In fact, the "bother" or "overhead" of passing the context object around is a good thing: it points out that having dependencies between the elements of your software project is not free. If you think that writing out the extra parameter is "too much work", then you're missing the forest for the trees: the dependency thus introduced has a much higher mental overhead than the mere mechanics of typing an extra parameter. After you pass that context a few times, typing it will be second nature and have 0 real overhead. The typing is cheap and doesn't require thinking, but keeping in mind the dependency and how it figures in the design of the overall system is anything but.
So: if you are trying to argue that introducing the dependency is worth it, then you have to back it up with actions and actually pass the context object around. The real cost is in the dependency, not the typing. Otherwise, it's a case of "talk is cheap" :)
One way of decreasing the apparent "cost" of passing such context objects is to upset the balance and make the context object actually do something, besides just carrying data. You would then use the context object to manipulate the objects for you, instead of calling the methods on the objects. This sort of "inversion" is quite handy, and often results in better design. After all, the presence of the context indicates that there's an overarching common state, and that perhaps too much functionality is delegated to the "end object", making it intertwined with the common state, whereas it may make more sense in the context object, making the end object less dependent on the presence of any particular external state.
You'd want the context to have methods that require "seeing the big picture", i.e. being aware of the presence of multiple objects, whereas the "leaf objects" (the ones with myMethod) should have methods that don't require the context, or that are general enough not to force any particular context class.
In your case, myMethod perhaps instead of working directly on an EntityContext could generate a functor or a similar action-wrapping object that performs the action, and this could then be applied by the caller (e.g. the context) to execute the database action. This way later it'll be easier to centrally manage the queue of database operations, etc.
When I refactor large projects, this sort of a "context inversion" comes in handy often, and the need for such patterns is very common. Usually, as large projects grow, the "leaf classes" start up lean, and end up acquiring functionality that belongs at a higher level. This is why using good tooling to explore the history of the repository is an imperative, and it's equally important that the entire repository history is available, i.e. that it was properly imported to git. I personally use DeepGit to trace the history of the code I work on, and find such tool indispensable. DeepGit is free as in beer for any use, and if you're not using a tool with similar functionality, you're seriously missing out, I think.
The need to pass contexts around is usually the indicator that a higher level has to be designed and introduced, and the "leafs" then need to be slimmed down, their context-using functionality moved out into the higher level. A few years down the road yet another higher level ends up being needed, although there are projects so far gone that when you just refactor them to make sense of the code base, two or three additional layers make themselves apparent!
I know of 2 ways that can be done. Consider you have the following method:
static void myMethod(string _stringA, string _stringB, string _stringC)
{
Console.WriteLine($"{_stringA},{_stringB},{_stringC}");
}
Create an overload method in the class. For example you could create an overloaded method like:
static void myMethod(string _stringA)
{
myMethod(_stringA, "stringB", "stringC");
}
The second way (which I would not advice it) is doing it the functional way like Javascript does (by using delegates):
public delegate void MethodDelegate(string _string);
static MethodDelegate mMethod1;
static MethodDelegate mMethod2;
static void Main(string[] args)
{
mMethod1 = delegate (string s) { myMethod(s, "method1-str-a", "method1-str-b"); };
mMethod1("str1");
mMethod2 = delegate (string s) { myMethod(s, "method2-str-a", "method2-str-b"); };
mMethod2("str2");
}

Reactive extensions delayed initialization

It's fairly established that doing work in ctors for types that are resolved using SimpleInjector is bad practice. Although this often leads to certain late initializations of such types, a particularly interesting case is Reactive Extensions subscriptions.
Take for instance an observable sequence that exhibits Replay(1) semantics (actually BehaviorSubject if we take the StartWith into account), e.g.
private readonly IObservable<Value> _myObservable;
public MyType(IService service)
{
_myObservable = service.OtherObservable
.StartWith(service.Value)
.Select(x => SomeTransform())
.Replay(1)
.RefCount();
}
public IObservable<Value> MyObservable => _myObservable;
Assume now, that SomeTransform is computationally expensive. From the point of view of SimpleInjector, the above is bad practice. Ok, so we need some kind of Initialize() method to call after SimpleInjector is finished. But what about our replay semantics and our StartWith()? Our consumers expect a value when they Subscribe (assume now that this is guaranteed to happen after initialization)!
How do we get around these restrictions in a nice way while still satisfying SimpleInjector? Here's a summary of requirements:
Don't do extensive work in the ctor (i.e. SomeTransform) should not run
_myObservable should be readonly
MyObservable should exhibit Replay(1) semantics
We should always have an initial value (hence the StartWith)
We do not want to Subscribe inside MyType and cache the value (we like immutability)
I experimented with creating an additional observable that starts with false and then gets set to true on initialize, and then merging that together with _myObservable, but couldn't quite get it to work. Additionally, it doesn't seem like the best solution. In essence, all I want to do is delay until Initialize() is done. There must be some way to do this that I'm not seeing?
One easy solution that comes to mind is the use of Lazy<T>
This could look like:
private readonly Lazy<IObservable<Value>> _lazyMyObservable;
public MyType(IService service)
{
_lazyMyObservable = new Lazy<IObservable<Value>>(() => this.InitObservable(service));
}
private IObservable<Value> InitObservable(IService service)
{
return service.OtherObservable
.StartWith(service.Value)
.Select(x => SomeTransform())
.Replay(1)
.RefCount();
}
public IObservable<Value> MyObservable => _lazyMyObservable.Value;
This will init the variable _lazyMyObservable without actually calling SomeTransform(). When a consumer asks for MyType.MyObservable the InitObservable code will be called one time and one time only. This postpones the initialization to the point where the code is actually used.
This will keep your constructor nice and clean and has no need to add initialization logic.
Note that the ctor of the Lazy<T> has several overloads that you can use if you may have issues with multithreading.
Injection constructors should be simple and reliable. This means that the following practices are frowned upon:
Doing any I/O operations inside the constructor. I/O operations can fail and make construction of the object graph unreliable.
Using the class's dependencies inside the constructor. Not only could a called dependency cause I/O of its own, sometimes injected dependencies are not (yet) fully initialized, and final initialization happens at a later point in time. Perhaps after the object graph has been constructed.
Considering how Reactive Extensions work, your MyType constructor doesn't seem to do any I/O. Its SomeTransform method is not called during the creation of MyType. Instead, the observable is configured to call SomeTransform when objects are pushed. This means that from a DI perspective, your injection is still 'simple' and fast. Sometimes your classes need some initialization on top of storing incoming dependencies. Creating and storing a Lazy<T>, for instance, is a good example. It allows delaying doing some I/O while still having more code than merely "receiving the dependencies."
But still you are accessing a dependency inside your constructor, which might cause trouble if that dependency, or its dependencies are not fully initialized. Further more, with Reactive Extensions you make a runtime dependency from IService back to MyType (you already have a design-time dependency from MyType to IService). This is very similar to working with events in .NET. Consequence of this is that it could cause MyType to be kept alive by IService, even when MyType lifetime is expected to be shorter.
So, strictly spoken, from a DI perspective this configuration might be troublesome. But it's hard to imagine a different model when working with Reactive Extensions. That would mean you have to move this configuration of the observables out of the constructors, and do it after the object graph has been constructed. But that will likely cause having to open up your classes so the Composition Root has access to the methods that need to be called. It also causes Temporal Coupling.
In other words, when using Reactive Extensions, it is probably good to have some design rules in place to prevent trouble. These rules could be:
All exposed IObservable<T> properties should always be fully initialized and usable after its type's construction.
All observers and observables should have the same lifetime.

Simple Injector auto-wiring with an Initialize()-Method

I'm using Simple injector successfully with constructor injection and I love the auto-wiring feature for the ctr-Arguments. Is there a similar auto-wire way for a initialize method?
So like instead of providing arguments to the constructor where doing async stuff is often impossible, things are provided to an Initialize() method with auto-wiring
public class A
{
// only std-ctor ()
[Init] // maybe mark needed?
void /*async*/ Initialize(IC c, IB b)
{
// get auto called by container and params auto-wired
// maybe do async stuff with b
}
}
// in Composition root (for simplicity):
container.RegisterSingleton<A>();
So the async possibility would be a plus feature.
[Update]
So async is reasonably not the feature you want in object graph creation. So let's not put the focus on that. But sometimes it may still be desireable to rather use init (i.e. if a ()-constructor is required). I realize that auto calling Initialize() by simple injector leads to nonsense. I just see the need sometimes to split object creation and initialization and auto-wiring is just way too cool. How would one then activate or implement that? So that simple Injector does auto-wire it for you? I hope I do not have to write an "initializer-class" where I have to 'pipe through' all dependencies. So that is the actual direction of the question (get ahold of Magic.AutoWire()).
public class SomeClassWithA
{
A _a;
public SomeClassWithA(A a)
{
_a=a;
}
void CalledLater()
{
Magic.AutoWire(_a);
// Initialize with auto-wire parameters was called
}
}
Although it is possible to extend Simple Injector to call an initialize method during object graph initialization, it is impossible to make this truly asynchronous, simply because Simple Injector lacks an asynchronous API. Without a "Task<T> GetInstanceAsync<T>()" method, the application would still have wait for I/O by blocking a thread, instead of using an I/O completion port, which would completely waste the benefits of using async.
But Simple Injector lacks such async feature and this is deliberate (and AFAIK most DI libraries lack such feature for the exact same reason). The construction of object graphs should be fast and should not consist of any I/O. Constructors (or initializers with dependencies) should do nothing more than store incoming dependencies, as Mark Seemann clearly stated here.
This basically means that you should delay any I/O till after object graph construction until the moment that an object is used for the first time. This not only keeps object construction simple, fast and reliable, it also makes it possible to verify the construction of your onject graph in isolation (without the existence of any I/O components such as a database or the file system).

How to avoid passing a context reference among classes

Dynamics CRM 2011 on premise. (But this problem exists in many situations away from Dynamics CRM.)
CRM plugins have an entry point:
void IPlugin.Execute (IServiceProvider serviceProvider)
(http://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.iplugin.execute.aspx)
serviceProvider is a reference to the plugin execution context. Anything useful that a plugin does requires accessing serviceProvider, or a member of it.
Some plugins are large and complex and contain several classes. For example, I'm working on a plugin that has a class which is instantiated multiple times. This class needs to use serviceProvider.
One way to get access to serviceProvider from all the classes that need it would be to add a property to all those classes and then to set that property. Or to add properties for the parts of serviceProvider that each class needs. Either of these approaches would result in lots of duplicate code.
Another approach would be to have a global variable in the scope of the thread. However, according to http://msdn.microsoft.com/en-us/library/cc151102.aspx one "should not use global class variables in plug-ins."
So what is the best way to have access to serviceProvider without passing it around everywhere?
P.S. If an example helps, serviceProvider provides access to a logging object. I want almost every class to log. I don't want to pass a reference to the logging object to every class.
That's not quite what the warning in the documentation is getting at. The IServiceProvider isn't a global variable in this context; it's a method parameter, and so each invocation of Execute gets its own provider.
For improved performance, Microsoft Dynamics CRM caches plug-in instances. The plug-in's Execute method should be written to be stateless because the constructor is not called for every invocation of the plug-in. In addition, multiple threads could be running the plug-in at the same time. All per invocation state information is stored in the context. This means that you should not use global class variables in plug-ins [Emphasis mine].
There's nothing wrong with passing objects from the context to helper classes which need them. The warning advises against storing something in a field ("class variable") on the plugin class itself, which may affect a subsequent call to Execute on the same instance, or cause concurrency problems if Execute is called by multiple threads on the same instance simultaneously.
Of course, this "globalness" has to be considered transitively. If you store anything in either the plugin class or in a helper class in any way that multiple calls to Execute can access (using fields on the plugin class or statics on either plugin or helper classes, for example), you leave yourself open to the same problem.
As a separate consideration, I would write the helper classes involved to accept types as specific to their function as possible - down to the level of individual entities - rather than the entire IServiceProvider. It's much easier to test a class which needs only an EntityReference than one which needs to have an entire IServiceProvider and IPluginExecutionContext mocked up.
On global variables vs injecting values required by classes
You're right, this is something that comes up everywhere in object-oriented code. Take a look at these two implementations:
public class CustomEntityFrubber
{
public CustomEntityFrubber(IOrganizationService service, Guid entityIdToFrub)
{
this.service = service;
this.entityId = entityIdToFrub;
}
public void FrubTheEntity()
{
// Do something with service and entityId.
}
private readonly IOrganizationService service;
private readonly Guid entityId;
}
// Initialised by the plugin's Execute method.
public static class GlobalPluginParameters
{
public static IOrganizationService Service
{
get { return service; }
set { service = value; }
}
public static Guid EntityIdToFrub
{
get { return entityId; }
set { entityId = value; }
}
[ThreadStatic]
private static IOrganizationService service;
[ThreadStatic]
private static Guid entityId;
}
public class CustomEntityFrubber
{
public FrubTheEntity()
{
// Do something with the members on GlobalPluginParameters.
}
}
So assume you've implemented something like the second approach, and now you have a bunch of classes using GlobalPluginParameters. Everything is going fine until you discover that one of them is occasionally failing because it needs an instance of IOrganizationService obtained by calling CreateOrganizationService(null), so it accesses CRM as the system user rather than the calling user (who doesn't always have the required privileges).
Fixing the second approach requires you to add another field to your growing list of global variables, remembering to make it ThreadStatic to avoid concurrency problems, then changing the code of CustomEntityFrubber to use the new SystemService property. You have tight coupling between all these classes.
Not only that, all these global variables hang around between plugin invocations. If your code has a bug that somehow bypasses the assignment of GlobalPluginParameters.EntityIdToFrub, suddenly your plugin is inexplicably operating on data that wasn't passed to it by the current call to Execute.
It's also not obvious exactly which of these global variables the CustomEntityFrubber requires, unless you read its code. Multiply that by however many helper classes you have, and maintaining this code starts to become a headache. "Now, does this object need me to have set Guid1 or Guid2 before I call it?" On top of that, the class itself can't be sure that some other code won't go and change the values of global variables it was relying on.
If you used the first approach, you simply pass in a different value to the CustomEntityFrubber constructor, with no further code changes needed. Furthermore, there's no stale data hanging around. The constructor makes it obvious which dependencies the class has, and once it has them, it can be sure that they don't change except in ways they were designed for.
As you say, you shouldn't put a member variable on the plugin since instances are cached and reused between requests by the plugin pipeline.
The approach I take is to create a class that perform the task you need and pass a modified LocalPluginContext (making it a public class) provided by the Developer Toolkit (http://msdn.microsoft.com/en-us/library/hh372957.aspx) on the constructor. Your class then can store the instance for the purposes of executing it's work just in the same way you would with any other piece of code. You are essentially de-coupling from the restrictions imposed by the Plugin framework. This approach also makes it easier to unit test since you only need to provide the execution context to your class rather than mocking the entire plugin pipeline.
It's worth noting that there is a bug in the automatically generated Plugin.cs class in the Developer Toolkit where it doesn't set the ServiceProvider property - At the end of the constructor of the LocalPluginContext add the line:
this.ServiceProvider = serviceProvider;
I have seen some implementations of an IoC approach in Plugins - but IMHO it makes the plugin code way too complex. I'd recommend making your plugins lean and simple to avoid threading/performance issues.
There are multiple things I would worry about in this design request (not that it's bad, just that one should be aware of, and anticipate).
IOrganizationService is not multi-thread safe. I'm assuming that other aspects of the IServiceProvider are not as well.
Testing things at an IServiceProvider level is much more complicated due to the additional properties that have to be mocked
You'd need a method for handle logging if you ever decided to call logic that is currently in your plugin, outside of the plugin (e.g. a command line service).
If you don't want to be passing the object around everywhere, the simple solution is to create a static property on some class that you can set it upon plugin execution, and then access from anywhere.
Of course now you have to handle issue #1 from above, so it'd have to be a singleton manager of some sort, that would probably use the current thread's id to set and retrieve the value for that thread. That way if the plugin is fired twice, you could retrieve the correct context based on your currently executing thread. (Edit Rather than some funky thread id lookup dictionary, #shambulator's ThreadStatic property should work)
For issue #2, I wouldn't be storing the IServiceProvider as is, but split up it's different properties (e.g. IPluginExecutionContext, IOrganizationService, etc)
For issue #3, it might make sense to store an action or a function in your manager rather than the object values themselves. For example, if rather than storing the IPluginExecutionContext, store a func that accepts a string to log and uses the IPlurginExeuctionContext to log. This allows other code to setup it's own logging, without being dependent on executing from within a plugin.
I haven't made any of these plugins myself, but I would treat the IServiceProvider like an I/O device.
Get the data you need from it and convert that data to format that suits your plugin. Use the transformed data to set up the other classes. Get the the output from the other classes and then translate back to terms the IServiceProvider can understand and use.
Your input and output are dependent on the IServiceProvider, but the processing doesn't have to be.
From Eduardo Avaria at http://social.microsoft.com/Forums/en-US/f433fafa-aff7-493d-8ff7-5868c09a9a9b/how-to-avoid-passing-a-context-reference-among-classes
Well, as someone at SO already told you, the global variables restriction is there cause the plugin won't instantiate again if it's called within the same context (the object context and probably other environmental conditions), so any custom global variable would be shared between that instances, but since the context will be the same, there's no problem in assigning it to a global variable if you want to share it between a lot of classes.
Anyways, I'd rather pass the context on the constructors and share it have a little more control over it, but that's just me.

Composition and interaction with owner instance

I was wondering what is the best practice for accessing the owner instance when using composition (not aggregation)
public class Manager
{
public List<ElementToManage> Listelmt;
public List<Filter> ListeFilters;
public void LoadState(){}
}
public class Filter
{
public ElementToManage instance1;
public ElementToManage instance2;
public object value1;
public object value2;
public LoadState()
{
//need to access the property Listelmt in the owner instance (manager instance)
//instance1 = Listelmt.SingleOrDefault(...
}
}
So far I'm thinking about two possibilities:
Keep a reference to the owner in the Filter instance.
Declare an event in the Filter class. The manager instance subscribe to it, and the filter throw it when needed.
I feel more like using the second possibility. It seems more OOP to me, and there is less dependencies between the classes ( any refactoring later will be easier),
But debugging and tracing may be a bit harder on the long run.
Regarding business layer classes, i don't remember seeing events for this purpose.
Any insight would be greatly appreciated
There is no concept of an "owner" of a class instance, there should not be any strong coupling between the Filter instance and the object that happens to have an instance of it.
That being the case an event seems appropriate: It allows for loose coupling while enabling the functionality you want. If you went with option #1 on the other hand you would limit the overall usefulness of the Filter class - now it can only be contained in Manager classes, I don't think that is what you would want.
Overall looking at your code you might want to pass in the relevant data the method LoadState operates on so it doesn't have to "reach out".
I recomend the reference to owner of filter instance. The event can be handled by more handlers and can change result of previous handler(s). And you propadly don't want change the owner during lifetime of Filter without notification the Filter instance.
My short answer : Neither.
First option to keep a reference to the owner is problematic for several reasons. Filter class no longer has a single responsibility. Filter and Manager are tightly coupled. etc.
Second option is only a little better, and yes I've used events in similar scenearios, it rarely if ever ends well.
It's difficult to give a definite advice without more specific details. Some thoughts:
1) Are you sure your classes are as they should be? Maybe there should be a class to compose a single ElementToManage and a single Filter ?
2) Who is responsible for creating a Filter? For example, if it is Manager, maybe the Manager can give the list as a construction parameter? Maybe you can create a FilterFactory class that does any needed initializations.
3) Who calls filter.LoadState()? Maybe the needed list could be passed as a parameter to the LoadState() method.
4) I frequently use an "Initialization Design Pattern" (my terminology) For example I'll have a BinaryTree where parent and child will point to each other. The Factory constructs the nodes in a plain state, and than calls an initialize method with other needed objects. The class becomes complicated because I probably need to ensure that an uninitialized object raises an error for every other usage, and need to ensure that an object is initialized only once, is initialized only through the Factory, etc. But if it works, it is usually the best solution, in my opinion.
5) I'm still trying to learn "Dependency Injection" and getting nowhere, I guess it may have something to do with your question. I wonder if someone will come with an answer involving Dependency Injection.

Categories

Resources