Subscribe to Methods & Tools
if you are not afraid to read more than one page to be a smarter software developer, software tester or project manager!
Software Development Blogs: Programming, Software Testing, Agile Project Management
Subscribe to Methods & Tools
if you are not afraid to read more than one page to be a smarter software developer, software tester or project manager!
You may believe it or not, but the post that drains most of the traffic of this blog, is the one about C# static interfaces !
Â
In october 2009, I simply tried to imagine where the idea of C# static interfaces could lead us, and, since then, I have more viewed pages (> 15%) on this post than on my home page !
Â
And since then, nothing moved in this area in the C# langage, and I don’t expect it to happen soon.
Â
But some other thing happened…
Â
F#Â
Yes F# is out and running on almost all platforms, and it can do what I described in the previous post.
Â
The thing is called Statically Resolved Type Parameters and is closer to C++ templates than from C# generics.
Â
The trick is that you can define an inline function with statically resolved types, denoted by a ^ prefix. The usage of defined methods on the type is not given here by an interface, but by a constraint on the resolved type :
let inline count (counter: ^T) =
let value = (^T: (member Count : int) counter)
value
here , the count function takes a counter of type ^T (statically resolved).
The second line express that ^T actually should have a member Count of type int, and that it will call it on counter to get the result value !
Â
Magic !
Â
Now, we can call count on various types that have a Count member property like :
type FakeCounter() =
member this.Count = 42;
or
type ImmutableCounter(count: int) =
member this.Count = count;
member this.Next() = ImmutableCounter(count + 1)
or
type MutableCounter(count: int) =
let mutable count = 0
member this.Count = count;
member this.Next() = count <- count + 1
without needing an interface !
For instance :
let c = count (new FakeCounter())
True, this is compile time duck typing !
Â
And it works with methods :
let inline quack (duck: ^T) =
let value = (^T: (member Quack : int -> string) (duck, 3))
value
This will call a Quack method that takes int and returns string with the value 3 on any object passed to it that has a method corresponding to the constraint.
And magically enough, you can do it with static methods :
let inline nextThenstaticCount (counter: ^T) =
(^T: (member Next : unit -> unit) counter)
let value = (^T: (static member Count : int) ())
value
this function calls an instance method called Next, then gets the value of a static property called Count and returns the value !
It also works with operators :
let inline mac acc x y = acc + x * y
notice the signature of this function :
acc: ^a -> x: ^c -> y: ^d -> ^e
when ( ^a or ^b) : (static member ( + ) : ^a * ^b -> ^e) and
( ^c or ^d) : (static member ( * ) : ^c * ^d -> ^b)
It accepts any types as long as they provide expected + and * operators.
Â
The only thing is that a specific implementation of the function will be compiled for each type on which it’s called. That’s why it called statically resolved.
Â
You can use this kind of method from F# code but not from C#.
Â
Anyway…
No need for static interfaces in C#, use F# !
Last week I made a big 3 hour presentation (oops I forgot the pause..) at the DevoxxFr conference.
Â
It was the second edition of this big Java oriented event in Paris, and a big success: 1400 attendees, 180 speakers for 160 presentations.
Â
I’ve seen a lot of interesting talks there and met nice people ! I can sincerely recommend it to anyone, even not fluent in Java.
Â
I posted the slides of my talk on SlideShare – french only.
Â
I’ll post a link the the recorded video as soon as it’s available.
Â
The slides don’t contain the details of the F# live coding of a Uno game, but it was quite similar to my SimpleCQRS F# implementation on GitHub.
Â
Someone noticed it was a F# presentation in a JVM conference while there was no F# at the last TechEd…
Â
I have still new comments and there are some Stack Overflow questions on the subject that show the response to the question is still unclear…
Â
Should you inject, or even use repositories in you entities ?
The response is two fold, and both go in the same direction, you shouldn’t.
Â
Of course, we’re discussing design here, so if in your specific case you find reasons more important than those invoked here, there’s always a possibility to decide to go as you wish…
Â
Injection and DDD patternsWhere talking Injection and Entities/Repositories here, so the first reason concerns what injection means in a Domain Driven Design environement.
Â
The wikipedia definition of the dependency injection pattern only makes references to objects or components without defining explicitly which kind of object or which kind of component…
Â
But a famous injection anti pattern can give use more information on what are injected components.
I call the Service Locator anti pattern.
Â
This make it clear that what we are looking for is a way to find service in a supple and configurable way.
I won’t explain here why the service locator is an anti pattern, but it makes it obvious that the use of injection is to provide access to services in the code.
Â
Since services are supposed to be stateless, their lifecycles are usually quite flexible. A service could be instanciated on each call, on each request or as a single instance without much difference. The injected service dependencies enable to compose services to replace implementations by configuration or for tests..
But even at runtime. A live configuration change could indicates to replace an injected service on next instantiation.
Â
Services and repositories are quite obviously not injected with Entities/Aggregates:
But could entities be injected with services or repositories ?
Â
An aggregate or an entity is not stateless as a service, it is statefull, and its member fields are here to maintain current state.
It seems quite odd to use those fields to store references to services that are obviously not part of the state.
It also links the referenced service lifecycle to the lifecycle of the entity itself.
Â
Most entities instanciation schemes in web applications are on a per call basis, and since most web application don’t do anything between calls, the response to the lifecycle problem is simply that everything in created and destroyed on each call.
But it is only a specific simplistic way to consider object lifecycle. What if you kept your entities longer in memory and reused them on next call to avoid roundtrips with the data storage ?
Having a reference to a service inside an entity state would make the live reconfiguration far harder to achieve : You would have to trash all current state and reload everything. There is no such problem with services since they’re meant to be stateless.
Â
Entities fields are meant to store state, no to reference services. Their lifecycles should not be coupled.
Â
Consistency boundaryÂ
The second reason is about the aggregate consistency boundary.
Â
Why would you typically need a reference to a repository inside an aggregate ?
Â
First reason would be to load sub entities when needed. It’s also called delay load.
Â
You shouldn’t need delay load in aggregates
The reason comes from the aggregate definitions. From wikipedia:
Aggregate: A collection of objects that are bound together by a root entity, otherwise known as an aggregate root. The aggregate root guarantees the consistency of changes being made within the aggregate by forbidding external objects from holding references to its members.
Â
The definition talks about object being bound together. Those objects – entities – have strong relationships, or grouping them in an aggregate makes little sense. When the relation is strong, you will need for each
aggregate method to change all objects in coordination, or none. If not, parts of your aggregate should not be here.
If an aggregate needs all its state for each operation, there is strictly no reason to use delay load.
Load all, use all, save all.
Â
The second reason would be to load entities in other aggregates.
You shouldn’t need references to entities in other aggregates
or at least not directly. The service calling the method on the aggregate will find information needed to call the method (which can contain information coming from other aggregates), but if you need a direct reference to another entity, it’s a clear indication that the aggregated boundary is wrong ! Put that other entity in the aggregate !
Â
Thus once your aggregate modeling is ok, there is really no reason to use a repository inside an entity.