C#: How to resolve this circular dependency? - c#

I have a circular dependency in my code, and I'm not sure how to resolve it.
I am developing a game. A NPC has three components, responsible for thinking, sensing, and acting. These components need access to the NPC controller to get access to its model, but the controller needs these components to do anything. Thus, both take each other as arguments in their constructors.
ISenseNPC sense = new DefaultSenseNPC(controller, worldQueryEngine);
IThinkNPC think = new DefaultThinkNPC(sense);
IActNPC act = new DefaultActNPC(combatEngine, sense, controller);
controller = new ControllerNPC(act, think);
(The above example has the parameter simplified a bit.)
Without act and think, controller can't do anything, so I don't want to allow it to be initialized without them. The reverse is basically true as well. What should I do?
ControllerNPC using think and act to update its state in the world:
public class ControllerNPC {
// ...
public override void Update(long tick)
{
// ...
act.UpdateFromBehavior(CurrentBehavior, tick);
CurrentBehavior = think.TransitionState(CurrentBehavior, tick);
}
// ...
}
DefaultSenseNPC using controller to determine if it's colliding with anything:
public class DefaultSenseNPC {
// ...
public bool IsCollidingWithTarget()
{
return worldQuery.IsColliding(controller, model.Target);
}
// ...
}

Separate the model of the controller from the concrete controllerService using an interface.
This is about project references in domain driven design, I wrote a small blog about this problem some time earlier:
http://www.mellekoning.nl/index.php/2010/03/11/project-references-in-ddd/

Use two-phase construction, whereby the objects are constructed with null references to their related objects, and you then call set methods to set the references:
ISenseNPC sense = new DefaultSenseNPC(worldQueryEngine);
IThinkNPC think = new DefaultThinkNPC();
IActNPC act = new DefaultActNPC(combatEngine);
controller = new ControllerNPC();
sense.setController(controller);
think.setSense(sense);
act.setSense(sense);
act.setController(controller);
controller.setAct(act);
controller.setThink(think);
// And now the objects are ready to use.

Would it be possible to use events for some of the communication between objects?

From my understanding, the 1st and the main thing is: Controller should not know about thinking, sensing, acting...
I see you have something like 'Update' method for controller and (I guess) controller need to do something depending to current 'thinking','sensing','acting'.
For such case I would add 3 more components on a model level: 'ThinkModel', 'ActModel', 'SenseModel'. They should represent state of corresponding process and know nothing about other world.
Your controller should receive this information from components (Thinking, Acting, Sensing) by methods like 'DoAction', 'ThinkingAbout', 'FeelingSomething' and store it inside.
In the same time it should have a set of events like 'ActionOccured', 'ThinkingOccured', 'SenseingOccured' (last can be phrased like 'FeeledSomething'). These events should be:
fired in case of any state changed;
provide corresponding object model;
should be listened by components.
As a result you will have controller to know about models only, and each component to refer to all models AND controller. Components need to know nothing about each other. Controller need to know nothing about components. And you will be able to create your object in the way like this:
IThinkModel modelThinkg = new ThinkModel();
IActModel modelAct = new ActModel();
ISenseModel modelSense = new SenseModel();
IController controller = new Controller(modelThinkg, modelAct, modelSense);
ISenseNPC sense = new DefaultSenseNPC(controller);
IThinkNPC think = new DefaultThinkNPC(sense);
IActNPC act = new DefaultActNPC(combatEngine, sense, controller);
Constructor of each component can look like this:
class DefaultSenseNPC
{
DefaultSenseNPC(IController controller)
{
_controller = controller;
_contoller.ThinkingAbout += ContollerReceivedNewThinking;
}
private ContollerReceivedNewThinking(IModelThinking modelNewThink)
{
_modelNewThink = modelNewThink;// store it for further calculations.
}
}
Hope this helps.
P.S. In some way, suggested 'architecture' seems similar to MVP patter used in applications with user interface.

Related

Different DBContexts possible at the Data access Layer?

Here is my current problem. Lets say I have a DBConext for Customers called CustomerContext and on for Employees called EmployeeContext. I have them in two different DBContexts to keep it smaller and simplified. When I want to create a new customer, I call my Customers BLL(Business Logic Layer) which will in turn create a new instance of the CustomerContext. Now that context will be passed to a other related BLLs to verify the information and add their own records to the context to be inserted. when a context is passed into a BLL, that BLL will not save the changes to the context, the Parent level procedure will do that.
This works fine except when I pass the context to the Notes BLL. Here If I define the context as CustomerContext I am okay, but I need to also use this with EmployeeContext. How can I pass the Context in and determine which one to use at runtime? I tried passing it in as an object, but then if I try to add it to the table, I get object does not contain a definition for Note. Any suggestions would be greatly appreciated.
Here is a sample of what I want it to do, but I get an error on the moContext.Notes.Add(oNote); line, because its an object and not the context. moContext could be either CustomerContext or EmployeeContext.
object moContext;
bool mbContextCreatedLocal;
public NotesDAL(ref object pContext)
{
moContext = pContext;
mbContextCreatedLocal = false;
}
public void InsertNote(Note pNote)
{
Note oNote = null;
oNote = new Note()
{
Note = pNote.Note.Trim(),
NoteCategoryID = pNote.NoteCategoryID,
Title = (string.IsNullOrEmpty(pNote.Title) ? null : pNote.Title.Trim()),
};
moContext.Notes.Add(oNote);
if (mbContextCreatedLocal )
{
moContext.SaveChanges();
}
}

Unit testing an existing ASP.NET MVC controller

I've read more and more about unit testing, and determined to put it to work. I dug out a project which is written with ASP.NET MVC using the repository pattern, dependency injection and EF. My first task was to unit test a controller. Here is a snippet from the controller to test:
IUserRepository _userRepository;
IAttachmentRepository _attachmentRepository;
IPeopleRepository _peopleRepository;
ICountryRepository _countryRepository;
public UserController(IUserRepository userRepo, IAttachmentRepository attachRepo, IPeopleRepository peopleRepo, ICountryRepository countryRepo)
{
_userRepository = userRepo;
_attachmentRepository = attachRepo;
_peopleRepository = peopleRepo;
_countryRepository = countryRepo;
}
public ActionResult Details()
{
UserDetailsModel model = new UserDetailsModel();
foreach (var doc in _attachmentRepository.GetPersonAttachments(Globals.UserID))
{
DocumentItemModel item = new DocumentItemModel();
item.AttachmentID = doc.ID;
item.DocumentIcon = AttachmentHelper.GetIconFromFileName(doc.StoragePath);
item.DocumentName = doc.DocumentName;
item.UploadedBy = string.Format("{0} {1}", doc.Forename, doc.Surname);
item.Version = doc.VersionID;
model.Documents.Add(item);
}
var person = _peopleRepository.GetPerson();
var address = _peopleRepository.GetAddress();
model.PersonModel.DateOfBirth = person.DateOfBirth;
model.PersonModel.Forename = person.Forename;
model.PersonModel.Surname = person.Surname;
model.PersonModel.Title = person.Title;
model.AddressModel.AddressLine1 = address.AddressLine1;
model.AddressModel.AddressLine2 = address.AddressLine2;
model.AddressModel.City = address.City;
model.AddressModel.County = address.County;
model.AddressModel.Postcode = address.Postcode;
model.AddressModel.Telephone = address.Telephone;
model.DocumentModel.EntityType = 1;
model.DocumentModel.ID = Globals.UserID;
model.DocumentModel.NewFile = true;
var countries = _countryRepository.GetCountries();
model.AddressModel.Countries = countries.ToSelectListItem(1, c => c.ID, c => c.CountryName, c => c.CountryName, c => c.ID.ToString());
return View(model);
}
I want to test the Details method and have the following queries:
1) The Globals.UserID property retrieves the current user from the session object. How can I easily test this (I'm using the built in VS2010 unit testing and Moq)
2) I'm making a call to AttachmentHelper.GetIconFromFileName() here which simply looks at the extension of a file and displays an icon. I'm also making a call to GetPersonAttachments in the attachment repository, a call to GetPerson, GetAddress and GetCountries as well as a call to an extension method created transform a List to IEnumerable of SelectListItem.
Is this controller action an example of bad practice? It's using lots of repositories and also other helper methods. From what I can see, unit testing this single action will require lots and lots of code. Is this counter productive?
Unit testing a simple controller in a test project is one thing, but when you get into real life code such as this it could become a monster.
I guess my question really is should I refactor my code to make it easier to test, or should my tests become much more complex to satisfy the current code?
Complex tests are as bad as complex code: they're prone to bugs. So, in order to keep your tests simple it's generally a good idea to refactor your application code to make it easier to test. For example, you should pull out the mapping code from your Details() method into separate helper methods. You can then test those methods very easily and not have to worry so much about testing all the crazy combinations of Details().
I've pulled out the person and address mapping parts below, but you could pull it apart even more. I just wanted to give you an idea of what I meant.
public ActionResult Details() {
UserDetailsModel model = new UserDetailsModel();
foreach( var doc in _attachmentRepository.GetPersonAttachments( Globals.UserID ) ) {
DocumentItemModel item = new DocumentItemModel();
item.AttachmentID = doc.ID;
item.DocumentIcon = AttachmentHelper.GetIconFromFileName( doc.StoragePath );
item.DocumentName = doc.DocumentName;
item.UploadedBy = string.Format( "{0} {1}", doc.Forename, doc.Surname );
item.Version = doc.VersionID;
model.Documents.Add( item );
}
var person = _peopleRepository.GetPerson();
var address = _peopleRepository.GetAddress();
MapPersonToModel( model, person );
MapAddressToModel( model, address );
model.DocumentModel.EntityType = 1;
model.DocumentModel.ID = Globals.UserID;
model.DocumentModel.NewFile = true;
var countries = _countryRepository.GetCountries();
model.AddressModel.Countries = countries.ToSelectListItem( 1, c => c.ID, c => c.CountryName, c => c.CountryName, c => c.ID.ToString() );
return View( model );
}
public void MapAddressToModel( UserDetailsModel model, Address address ) {
model.AddressModel.AddressLine1 = address.AddressLine1;
model.AddressModel.AddressLine2 = address.AddressLine2;
model.AddressModel.City = address.City;
model.AddressModel.County = address.County;
model.AddressModel.Postcode = address.Postcode;
model.AddressModel.Telephone = address.Telephone;
}
public void MapPersonToModel( UserDetailsModel model, Person person ) {
model.PersonModel.DateOfBirth = person.DateOfBirth;
model.PersonModel.Forename = person.Forename;
model.PersonModel.Surname = person.Surname;
model.PersonModel.Title = person.Title;
}
Just wanted to elaborate a little bit on the subj. What we're trying to unit test is the logic. Not too much of it in the controller. So in this particular case I would do the next: extract method that returns the model not the view. Inject mocked repos into the controller object. And after exercising the mapping would insure that all the properties are filled with expected values. Another way of doing that is to generate JSON and insure that all the properties are filled appropriately. However, I would strive to put unit tests on the mapping part itself and then would consider BDD for the integration tests.
I'd move all of your Model construction code into the constructor of the model itself. I prefer to keep the controllers restricted to a very few simple tasks:
Selecting the proper view (if the controller action allows for more than one view)
Selecting the correct view model
Permissions/security
View model validation
Thus, your Details controller becomes much simpler and testing becomes more more managable:
public ActionResult Details() {
return View(new UserDetailsModel(Globals.UserId);
}
Now that your controller is tight and testable, let's look at your model:
public class UserDetailsModel {
public UserDetailsModel(int userId) {
... instantiation of properties goes here...
}
... public properties/methods ...
}
Again, the code in your model is encapsulated and only needs to worry specifically about it's properties.
As already mentioned by #KevinM1, if you're practicing TDD (you have that tag in your question), you're writing the test before the implementation.
You first write a test for your controller's Detail method. When you write this test you notice that you need to map a person to a UserDetailsModel. When writing test you "hide complexity" that don't belong to the actual implementation of what you want to test behind an abstraction. In this case, you'd probably create an IUserDetailModelMapper. When this first test is written, you make it green by creating the controller.
public class UserController
{
ctor(IUserRepository userRepo, IUserDetailModelMapper mapper){...}
public ActionResult Details()
{
var model = _mapper.Map(_userRepo.GetPerson());
return View(model);
}
}
When you later write test for your mapper, you said you need to use some static prop called Globals.UserId. Generally I would avoid static data if possible, but if this is a legacy system you need to "objectify" this to get i testable. One simple way is to hide it behind an interface, something like this...
interface IGlobalUserId
{
int GetIt();
}
...and do an implementation where you use your static data. From now on, you can inject this interface instead to hide the fact that it's static data.
The same thing goes for "AttachmentHelper". Hide it behind an interface. Generally though, there should be alarm bells for XXXHelpers - I would say it's a sign of not placing method where they should be (part of an object) but rather a mix of all kinds of stuff that been mixed together.

Dependency Injection "nesting" in related methods

We're using DI and Unity to work with different dependencies (generally, database and repository classes, dto to entity mappers, etc)
Right now we're trying to create smaller functions that perform tasks that try to be independend from each other, in order to increase testability and also to avoid methods that have lots of different responsibilities, to avoid coupling
One question that I have is, how should DI be used when we have methods that rely on other inner methods, when the nesting is not trivial. For example, consider the following example (just a concept, not real working code):
public ProcessedOrder ProcessOrders(Order inputOrder)
{
foreach (var line in inputOrder.OrderLines)
{
var someData = LineProcessor(line);
}
}
public SomeData LineProcessor(OrderLine line)
{
/* do some stuff*/
var OtherData = ThingProcessor(null,line.SomeStuff);
var ret = new SomeData();
// assign values, more stuff
return ret;
}
public OtherData ThingProcessor(IDep1 someDependency, SomeStuff stuff)
{
someDependency = someDependency ?? ServiceLocator.Resolve<IDep1>();
var ret = someDependency.DoThings(stuff);
return ret;
}
Ok, so far the example shows that we have 3 functions, that could theoretically be called on their own. there's some injected dependency in the ThingProcessor, and if it's null then it tries to resolve it.
However, this is a somehow simple example, but I see something I don't like so much. For instance, I'm calling ThingProcessor with a null value in the first param. So I can say, ok, I modify the signature of LineProcessor to have it injected, so that he pass it in to the other function that needs it. However, he really doesn't need it, it's not its dependency but the function that he's calling.
So here I don't know what approach is the more correct one, if the one that i'm showing, or if I should pass the correlated dependencies across layers. If I do this last thing, then the outermost function will be a mess, because it'll have a long list of dependencies that it will feed to everyone that's below it.
However, the "null approach" I don't like very much, so I'm pretty sure that something's wrong somewhere, and there's probably a better way to design this.
What's the best approach??? Remember, all functions must be used independently (called on their own), so for example I may call just ThingProcessor at some point, or at another one only LineProcessor.
UPDATE :
public CommonPurposeFunctions(IDep1 dep1, IDep2 dep2 ....)
{
this.Dep1 = dep1;
this.Dep2 = dep2;
[...]
}
public ProcessedOrder ProcessOrders(Order inputOrder)
{
foreach (var line in inputOrder.OrderLines)
{
var someData = LineProcessor(line);
}
}
public SomeData LineProcessor(OrderLine line)
{
/* do some stuff*/
var OtherData = ThingProcessor(line.SomeStuff);
var ret = new SomeData();
var morethings = this.Dep2.DoMoreThings();
// assign values, more stuff
return ret;
}
public OtherData ThingProcessor(SomeStuff stuff)
{
var ret = this.Dep1.DoThings(stuff);
return ret;
}
The approach we use is constructor injection, then we store the dependency in a private member field. The container wires up the dependencies; so the number of classes and constructor parameters doesn't really matter.
This works for services. If the dependencies across calls have meaningful state, you will have to pass them in to each call. But, in that case, I'd question if the methods really need to be public methods in their own classes.
You want to end up with a design that eliminates the service locator and truly injects the dependencies.
Does the null object pattern help?
http://en.wikipedia.org/wiki/Null_Object_pattern

testing using unity and accessor classes

So I need to test some view models that have a private field containing an adapter, this adapter gets manipulated via ICommands / input / etc from the views, I think this is a pretty common model, the view exposes some public properties that are specific to what that particular view is all about and then then the adapter is concelled in a private field. Now my problem is testing. I am using Unity to register an instance of that adapter and then each view model gets that same instance of course but I can't test it cause it is private so I created an accessor class but I can't figure out how to create and instance of it. Maybe some code will help explain what I am trying to do. Now keep in mind I am new to testing so if I am totally confused about something please let me know.
[TestInitialize]
public void Initialize()
{
container = new UnityContainer();
container.RegisterType<IEventAggregator, EventAggregator>();
container.RegisterType<IRegionManager, RegionManager>();
//Notice that I am not calling registertype but later on I call container.Resolve asking for
//CreateRgaViewModel - this is because I don't have to regiter the types / instances of
//whatever I am directly asking for but I do have to register anything it depends on.
//container.RegisterType<CreateRgaViewModel>();
var adapter = new RgaWizardAdapter(container);
//So we don't want to get any data at this point because this is not an integrration test
//adapter.InitializeRga(873632);
container.RegisterInstance<IRgaWizardAdapter>("RgaAdapterInstance", adapter);
var appCommands = new ApplicationCommands(container);
container.RegisterInstance<IApplicationCommands>(appCommands);
}
[TestMethod]
public void CanCreate_CreateRgaViewModelAndGetNamedInstanceOfRgaDocument()
{
try
{
//this fails
//CreateRgaViewModel_Accessor createRgaViewModel = container.Resolve<CreateRgaViewModel_Accessor>();
//this works
CreateRgaViewModel createRgaViewModel = container.Resolve<CreateRgaViewModel>();
Assert.IsNotNull(createRgaViewModel, "CreateRgaViewModel was null");
}
catch (Exception ex)
{
}
}
My problem is that I find a lot of stuff on testing but it seems to be specific to using silverlight. I am not creating a silverlight app, this is desktop WPF / MVVM app.
Thanks for your help

Moling DataContext with MS Moles?

How can I mole the DataContext that I'm using in a class to write messages to a table. I'd like to assert that the table LINQ is writing to has the expected count of messages. Here's what i have so far.
var context = new MJustTestingDataContext();
MyMessagewriter writer = new MyMessageWriter(context);
var messageList = new List<MIncmoingMessage>();
MTable<MIncomingMessage> messageTable = new MTable<MIncomingMessage>();
messageTable.Bind(messagesLinqList.AsQueryable());
If I use this code with xUnit in my class under test I'll get this exception
Microsoft.Moles.Framework.Moles.MoleNotImplementedException: DataContext.Dispose() was not moled.
What am I missing here and how to implement DataContext.Dispose() on the mole? I'm using moles standalone without Pex.
When you create a new Mole the default behavior for its methods and properties is to throw a MoleNotImplementedException whenever they are called.
To implement the mole you can do context.Dispose = () => {}; which means that nothing happens when the Dispose method gets called on the moled instance.
I reread the question and you probably are having a problem since Dispose is defined in a base class. To mole base method you need to do the following:
var context = new MJustTestingDataContext();
var baseContext = new MDataContext(context);
baseContext.Dispose = () => {};
You'll need to implement every property/method that gets called by the code under test or you can set the default behavior for the mole instance globally using the method BehaveAsDefaultValue. This way every method in the mole will do nothing and return the default value for it's return type if one exists instead of throwing a MoleNotImplementedException. However if you require this behavior it's better to use a stub than a mole.
I'm having trouble understanding what your test is doing. I had to do something similar yesterday, so I'll share my experience. First, it's important to understand that you don't need to use all the MoleTypes to test your code -- you just need to use Moles to redirect certain parts of your code to lambda expressions. Given a method that does this:
get a list of users to modify from the database
modify every user in the set
send the new set back to the database
I'd like to redirect 1 and 3 to not use the database. For instance, I can redirect the call to SubmitChanges (3) via this code:
bool hitSubmitChanges = false;
int changeCount = 0;
IList<object> updates = null;
// more code here...
// redirect DataContext.SubmitChanges() to a lambda to catch updates
MDataContext.AllInstances.SubmitChanges = (c) =>
{
changeCount = c.GetChangeSet().Updates.Count;
updates = c.GetChangeSet().Updates;
hitSubmitChanges = true;
};
That (and the call to get the users) would be the only Moletypes I'd use in the test. The rest of it would be normal. Then I can use assertions to check the values of changeCount, updates and hitSubmitChanges.

Categories