I have a controller which contains a few private read only interface properties which it needs in order to get data by calling a service which is then used to populate models etc
private readonly ISomeInterface _someObject;
Which gets set in the Controllers constructor:
public ... (ISomeInterface someInterface, ...) {
...
_someObject = someObject
}
_someObject is then used in a call to the service layer to get data.
I had to add another property to the controller but now when I build the soloution I get the following error:
CA1506 : Microsoft.Maintainability : 'ControllerName' is coupled with 87 different types from 30 different namespaces. Rewrite or refactor this class's methods to decrease its class coupling, or consider moving some of the class's methods to some of the other types it is tightly coupled with.
It asks me to reduce the coupling of the class, I understand that one way of doing this is to code against interfaces (abstractions) - which I'm already doing by adding the interface property? It seems by adding one more property it takes it past the threshold for flagging up this error.
If I remove it, I can't get the data I need? What do I need to modify?
How many actions does your controller have? Do you have a view model for each action? Do you have an input model for each action? Are you interacting with different classes for each controller action? You may need to split your controller up into multiple controllers to make it do less giving it fewer reasons to change and also fewer dependencies. Although using an interface would decouple the controller from the specific implementation of ISomeInterface it doesn't do anything in terms of that warning. Changing to using the Interface didn't reduce the number of types... it just changed from concrete type to an interface type.
The problem is warning against having one class that does many many things. Having many dependencies suggests the class is doing too much and should be divided up. For example if this controller has say an action for "Bake Pie" and "Eat Pie" and "Make Ice Cream" and "Deliver food" you could move "deliver food" to a brand new class... you could break out the Make Ice Cream as well and then you would evaluate if Bake Pie and Eat Pie should stay together in the same class or be put in separate classes. The pies debate opens a can of worms which folks would debate.
see: SOLID (object-oriented design)
Do you have code that has to call 2 or more different data access classes that then calls another class to to create a view model. You could move that whole operation to a new class thus reducing your dependency on 3 classes down to 1.
Related
I am trying to make a class that has two constructors, both with three arguments. One constructor is called if a user will be added, the other if the user is just being updated:
public class RequestController : IRequestController
{
public RequestController(IConnector, IAddRequestHandler, IAddReplyHandler) { ... }
public RequestController(IConnector, IUpdateRequestHandler, IUpdateReplyHandler) { ... }
}
I am aware that Unity doesn't appreciate multiple constructors of the same length and I have been trying to resolve this issue. So far, I can only find detailed explanation for if there are multiple constructors of length 1. This is what I have so far:
var container = new UnityContainer();
container.RegisterType<IRequestController, RequestController>("addConstructor",
new InjectionConstructor(typeof(IMQSeriesConnector), typeof(IAddRequestHandler), typeof(IAddReplyHandler)));
container.RegisterType<IRequestController, RequestController ("updateContructor",
new InjectionConstructor(typeof(IConnector), typeof(IUpdateRequestHandler), typeof(IUpdateReplyHandler)));
I think the next step is something along the lines of:
container.Resolve<IRequestController>("addConstructor",
new DependencyOverride(typeof(IConnector), typeof(IAddRequestHandler), typeof(IAddReplyHandler)));
container.Resolve<IRequestController>("updateConstructor",
new DependencyOverride(typeof(IRequestController), typeof(IAddRequestHandler), typeof(IAddReplyHandler)));
But this, of course, does not work. What am I missing for the "container.Resolve" piece?
I am trying to make a class that has two constructors, both with three arguments
This is where you go wrong. Your application components should have exactly 1 public constructor. Having multiple is an anti-pattern, as explained here. In short:
multiple constructors are redundant, ambiguous, make your DI configuration fragile, and lead to maintainability issues.
In your case you have one constructor with an IAddRequestHandler dependency and a different constructor with an IUpdateRequestHandler dependency.
What you probably are trying to achieve is to build an object graph with only dependencies that are required for the current request, but this doesn't make sense for multiple reasons.
First of all, since injection constructors should be simple, the construction of object graphs (even really big ones), should be really fast. So trying to optimize this does not make sense. From that point of view, your controller should have one constructor, and it should accept (and require) all the dependencies that class needs.
It might also indicate that your controller actually does too much and therefore violates the Single Responsibility Principle. You probably should split up this controller into two separate classes, each with (still) one constructor. This immediately makes your object graph narrower and smaller as well.
I am currently building an application using .net 4.6, MVC 5 and unity 4. I have a controller which looks like the below:
public class ExamController: Controller {
private IEducationService _eduService;
public ExamController(IEducationService eduService) {
_eduService = eduService;
}
}
And Unity injects the service with:
container.RegisterType<IEducationService, EducationService>();
Recently we are adding other Action methods to this controller which will need other services. for example, if I now have an ExperienceService, I could add to that to Unity and change the controller's constructor to take that as well:
public ExamController(IEducationService eduService, IExperienceService _expService )
problem is I don't want both available all the time, they should be available based on which Action method is called. I can make separate constructors for each, but I'm not sure then how to get Unity to make one instead of both, based on which Action method is getting called.
Using multiple constructors on injectables is anti-pattern.
Furthermore, constructors should be simple, so the worry of creating extra objects which aren't used is misguided (unless of course you are violating this rule). Creating objects is very cheap when there is nothing in the constructor but assignment statements, so injecting 1 or even 100 more is probably not going to have a huge impact on performance.
You should also limit the number of services a controller has. If you have more than 3 or 4, you are probably violating the Single Responsibility Principle and should consider refactoring to facade services that each have a single responsibility. The result is that you will have an object graph that looks more like a pyramid with a few dependencies at the top and those dependencies will each have a few more until you get to the bottom where there are none.
Related: Rebuttal: Constructor over-injection anti-pattern
Rather than have the dependencies injected and available to the entire class, you could simply resolve the dependency in the action method where you need it using the ServiceLocator:
var expService = ServiceLocator.Current.GetInstance(typeof(IExperienceService));
You would first need to register Unity's ServiceLocator:
ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(container));
Example
Just a quick note: The Service Locator pattern is considered an anti-pattern.
i'm working on a tile editor. In the editor you can load a tile map. Each tile map can have multiple layers. A tile map has a list of it's layers. I now need tile map properties in the layer class (things like tile width/height e.g.). I'm now asking myself what is the best way to do this.
I could make a bidirectional relationship by introducing a tilemap property in the layer class, so that i have access to everything i need from there. But then i would have to take care of two sides of the relationship.
I could give all the needed properties to the layer class with the constructor, but then they basicly become layer properties (aka they are different objects for every layer).
Same as 2 but give the properties to the layer with "ref" paramter.
I could make a class called something like TileMapLayerProperties where i put all the properties in and then pass the object to the layer classes. Advantage would be that all the properties would be the same and only the tileMapLayerProperties-reference would be per instance. Another advantage would be the "definition" of the layer constructor becoming much shorter.
So any suggestions / tips would be appreciated.
A bi-directional association (1) might be OK or not, depending on what properties and methods a tile map contains and what a layer should be able to know and access. If a tile map has a DeleteAllLayers method and layers should not be able to call it, then layers cannot have direct access to their parent.
Creating a dedicated property object (4) seems more clean to me. That way you have one object with all necessary information that you can pass around, but it does not contain more than that, especially it does not allow calling destructive methods etc.
Passing the properties to the constructor (2) is similar to (4), but more verbose and less object-oriented. It's fine when you have 1 or 2 properties, but with more than a few it gets ugly and unmaintainable.
But there is another problem: If the properties are of immutable types (e.g. int, string), then the layers do not see changes made in the map. They only see their private copy!
I don't understand (3). How does the ref keyword change (2)? It only allows the callee to change the value of a variable passed by the caller. Or do you mean objects with reference types?
Another solution
Interfaces would be another way to solve this. You could create a ITileMapLayerProperties interface that provides all the properties and pass it to the layer's constructor. The map could either implement the interface itself or contain a TileMapLayerProperties object that implements the interface. But the layer does not need to know this.
Option 2 would work for what you are trying to do, and you may not need to include the 'ref' keyword.
I'm curious, what kind of datamembers are you trying to access from the child classes? If they are collections then you may not need the 'ref' keyword.
Another option would be to make the parent class static, but I'm not sure if this is the outcome you're looking for. Can you load more than one tile map at a time? If not, consider the static class option.
I think option is 3 is better. You can pass a reference of your ParentClass to the ChildClass and can have directly access to all public properties. I suggested it better because what ever changes you will make whether from ChildClass or ParentClass, all other layers will inherit those changes.
I have a database that contains "widgets", let's say. Widgets have properties like Length and Width, for example. The original lower-level API for creating wdigets is a mess, so I'm writing a higher-level set of functions to make things easier for callers. The database is strange, and I don't have good control over the timing of the creation of a widget object. Specifically, it can't be created until the later stages of processing, after certain other things have happened first. But I'd like my callers to think that a widget object has been created at an earlier stage, so that they can get/set its properties from the outset.
So, I implemented a "ProxyWidget" object that my callers can play with. It has private fields like private_Length and private_Width that can store the desired values. Then, it also has public properties Length and Width, that my callers can access. If the caller tells me to set the value of the Width property, the logic is:
If the corresponding widget object already exists in the database, then set
its Width property
If not, store the given width value in the private_Width field for later use.
At some later stage, when I'm sure that the widget object has been created in the database, I copy all the values: copy from private_Width to the database Width field, and so on (one field/property at a time, unfortunately).
This works OK for one type of widget. But I have about 50 types, each with about 20 different fields/properties, and this leads to an unmaintainable mess. I'm wondering if there is a smarter approach. Perhaps I could use reflection to create the "proxy" objects and copy field/property data in a generic way, rather than writing reams of repetitive code? Factor out common code somehow? Can I learn anything from "data binding" patterns? I'm a mathematician, not a programmer, and I have an uneasy feeling that my current approach is just plain dumb. My code is in C#.
First, in my experience, manually coding a data access layer can feel like a lot of repetitive work (putting an ORM in place, such as NHibernate or Entity Framework, might somewhat alleviate this issue), and updating a legacy data access layer is awful work, especially when it consists of many parts.
Some things are unclear in your question, but I suppose it is still possible to give a high-level answer. These are meant to give you some ideas:
You can build ProxyWidget either as an alternative implementation for Widget (or whatever the widget class from the existing low-level API is called), or you can implement it "on top of", or as a "wrapper around", Widget. This is the Adapter design pattern.
public sealed class ExistingTerribleWidget { … }
public sealed class ShinyWidget // this is the wrapper that sits on top of the above
{
public ShinyWidget(ExistingTerribleWidget underlying) { … }
private ExistingTerribleWidget underlying;
… // perform all real work by delegating to `underlying` as appropriate
}
I would recommend that (at least while there is still code using the existing low-level API) you use this pattern instead of creating a completely separate Widget implementation, because if ever there is a database schema change, you will have to update two different APIs. If you build your new EasyWidget class as a wrapper on top of the existing API, it could remain unchanged and only the underlying implementation would have to be updated.
You describe ProxyWidget having two functions (1) Allow modifications to an already persisted widget; and (2) Buffer for a new widget, which will be added to the database later.
You could perhaps simplify your design if you have one common base type and two sub-classes: One for new widgets that haven't been persisted yet, and one for already persisted widgets. The latter subtype possibly has an additional database ID property so that the existing widget can be identified, loaded, modified, and updated in the database:
interface IWidget { /* define all the properties required for a widget */ }
interface IWidgetTemplate : IWidget
{
IPersistedWidget Create();
bool TryLoadFrom(IWidgetRepository repository, out IPersistedWidget matching);
}
interface IPersistedWidget : IWidget
{
Guid Id { get; }
void SaveChanges();
}
This is one example for the Builder design pattern.
If you need to write similar code for many classes (for example, your 50+ database object types) you could consider using T4 text templates. This just makes writing code less repetitive; but you will still have to define your 50+ objects somewhere.
What makes you determine to create a new controller instead of adding more actions to an existing controller? Where do you draw the line and WHY?
What certainly does not get into the picture is the number of actions¹ -- at least in the sense that "oh, I 'm over 50 actions in this controller, let's start another one".
The guideline² should be: controllers are a logical group for actions that operate on the same type of object (the same type of model might be a better definition). If it so happens that you have a model so rich in functionality that there are 30 separate actions that can be performed on it, go ahead and put them in the same controller.
On the other side of the coin: if you have simple models and you find yourself writing controllers with only a few actions each, that should be a reason to feel good about the maintainability of the application rather than a reason to worry.
Notes:
¹ Of course, a controller with that many actions is a red flag for possible code abuse so the number should come into consideration -- just not as some kind of hard rule.
² And it's really a guideline -- the aim here is to build a maintainable system, not to follow some religious scripture.
The major factor that should determine when to create a new controller is the logic/functionality they perform. You'll want to make sure you separate concerns:
public class ProfileController { }
public class MainController { }
public class AccountController { }
public class ShoppingCartController { }
Each of the previous controllers are used to coordinate the communication between their corresponding domain services/models and their views.
As a general rule of thumb, I keep all action as simple as i can, if they get big or too many then i see if i can creater helper functions.
I have a controller per DB entity if necessary.
So for example I would have a User controller, a Cart controller, an Item controller etc etc.
I dont think there are any specific rules. Its just about keeping it all logical. If its logical to you then thats generally all that matters, unless you are in a team, then it needs to be logical to everyone.
Hope this helps.