I’m running around in circles, so I thought I should try to draw it out. Click to zoom in if not legible; text below explaining.
All the words are driving me nuts. So I added A,B,C,D to the diagram above.
- A = the layer that talks network transport stuff, like Signal/R.
- B = the layer of the game that cares about booting up, shutting down, who is logged into the game, loading and unloading of realms.
- This stuff should NOT be directly available to in-game objects to mess with!
- C = subset of B. This is the stuff that should be available to in-game objects. It’s the O/S of the game, as it were.
- D = game code. In the case of wizard-coded realms, probably gets scanned to make sure it has no assembly references, and in days of old might have run under CAS.
- I’m not actually going to secure it, just want to make sure its probably securable.
- A should not know about all the stuff in B; just bare minimums to talk network occurences to.
- B should definitely not know about the specifics of A. In fact, I’d say B is an assembly that HAS NO REFERENCE to Signal/R.
- D should not know about B. I’d go with: D can ONLY have an assembly reference to C, and NOTHING else; if something is to be made available to code in D, it must be added to C as a pass-through.
- B & C can know all about each other.
Singletons vs Static vs ..
Lets call “C” the driver layer. Ie, IDriver.FindObjectByName() would be an example.
For all the code in the Mudlib, right now, it does stuff like Driver.Instance.FindObjectByName().
It might be better to use IoC and take an IDriver in the constructor, and then call _driver.FindObjectByName(). HOWEVER, then I get into things like “Can I have IoC limit which objects can be created”, and “I want to make sure as the objects are created that I can keep track of realms and stuff like that”, and all of a sudden IoC is too nice a tool to use. I’m sure it could be used with guards on it, but .. leave that to somebody else, I have no joy in solving that.
So then I could go with how many libraries get a hold of things – (static class DotNetMud.XXX).Driver. Always gets you the same one every time.
But if I’m doing that, why not just have a static class, Driver.FIndObjectByName()? No, I don’t want to do this, because I MIGHT want people to be able to unit test their mudlib objects, and I want the driver to at least be an IDriver so it can be mocked somehow.
So, I think where its going is, I’ll have a poor man’s IoC. DotNetMud.Global.Driver gets you the driver.
Who References Whom? How to deal with the Inverse?
D references C for sure.
A references and feeds B, including telling it how to talk back to A (via Lambda’s)
B is configured to know how to get to D.
C, when asked, can create objects from D. but it only knows D through configuration.
C needs access to stuff in B
B doesn’t need much from C/D, other than the interactives list, I think.
So there’s another guy, @, who:
- reads configuration to determine
- Who is D
- Who is D.GameSpecifics
- Creates or Gets Singleton of B
- Creates or Gets Singleton of C
- Informs B of C or C or B or whatever. Not sure about this part yet. Probably they each know each other’s interface.
- Tells C enough stuff about D so that it can create objects from D on demand.
- Tells A about B
- I would say creates A, but … SignalR does its own creation. So really more like when A is created, self-registers the context somewhere and triggers something so that A can talk to B.
Right now its all in one assembly.
This stuff is TOUGH.
And it gets tougher with code loaded on the fly. I don’t think I’m going to deal with that yet.
No wonder when I open up the project, this stuff isn’t flowing well.
How to get it there
I think I should probably get everything living in the same assembly at first, except under a web server rather than a console app.
Then, get the singleton-reference stuff in place. DotNetMud.Global.xxx. Change all references to do that.
Then, peel out the MudLib to its own thing. It still references all of B/C combined.
Then, peel out C to its own thing.
Then, peel out B to its own thing, separate from A.
This is a several-hour project, I fear.