I'm currently building an ASP.Net MVC 4 SAAS application (C#) and am stuck on designing the plans. I mean if a customer picks Plan A they should have access to some things and if they pick Plan B they get access to others and so on.
The Part that I'm stuck on is be best practice of sharing the account's plan with all of the actions. I realize having global variables are bad practice and all but I really don't want to take round trips to the DB to get the plan on every action.
What I'm thinking of doing is something like This SO answer where they just declare a static model and set it at some point and access it later on. In your opinion, is this the best way of doing this? is there a better way?
I think best practice is you should include an IoC in your project and inject a configuration object to your controller.
Example code of a controller:
public class YourController : Controller
{
private IConfigService _configService;
//inject your configuration object here.
public YourController(IConfigService configService){
// A guard clause to ensure we have a config object or there is something wrong
if (configService == null){
throw new ArgumentNullException("configService");
}
_configService = configService;
}
}
You could configure your IoC to specify singleton scope for this configuration object. In case you need to apply this pattern to all your controllers, you could create a base controller class to reuse code.
Your IConfigService
public interface IConfigService
{
string ConfiguredPlan{ get; }
}
Your ConfigService:
public class ConfigService : IConfigService
{
private string _ConfiguredPlan = null;
public string ConfiguredPlan
{
get
{
if (_ConfiguredPlan == null){
//load configured plan from DB
}
return _ConfiguredPlan;
}
}
}
This class is easily extended to include more configurations like connection String, Default timeout,...
We're passing in an interface to our controller class, it's easy for us to mock this object during unit testing.
Related
I will use a very simple example to describe my questions. Let's say I have a class to handle database calls
public class DatabaseAccessLayer : IDatabaseAccessLayer
{
public DatabaseAccessLayer(string uid, string password, string server)
{
// build connection object and so on
}
}
Then I have a class to use it
public class MyBusinessService : IBusinessService
{
public MyBusinessService(IDatabaseAccessLayer dal)
{
}
}
If I use Unity as example, I would typically wire up the IoC container this way
container.RegisterType<IDatabaseAccessLayer, DatabaseAccessLayer>(new InjectionConstructor("my_uid", "my_password", "my_server"));
container.RegisterType<IBusinessService, MyBusinessService>();
It works well if I define the parameters as known values when the IoC container is set up as application starts, for example typical web application has the values in the configuration file.
However there is one requirement that I have to pass the parameters (uid, password, server) to data access layer class for every single business service call because the values could be different each time. It looks like I have no way to use IoC container in this case.
Anybody has some comments, shall I abandon IoC container in this case or there is a better way to use IoC container?
I'm creating a Web API and I'm using dependency inject wit Ninject.
I have:
IRTWRepository
IModelFactory
I'm injecting those 2 into my controllers like this.
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IRTWRepository>().To<RTWRepository>();
kernel.Bind<RTWAPIContext>().To<RTWAPIContext>();
kernel.Bind<IModelFactory>().To<ModelFactory>();
}
My RTWRepository constructor looks like this
public class RTWRepository :IRTWRepository
{
private RTWAPIContext _context;
public RTWRepository(RTWAPIContext context)
{
_context = context;
}}
My ModelFactory constructor looks like this
public class ModelFactory : IModelFactory
{
private IRTWRepository _repo;
public ModelFactory(IRTWRepository repo)
{
_repo = repo;
}
}
I have a Controller that looks like this:
public MaterialsController(IRTWRepository repository,IModelFactory modelFactory)
: base(repository,modelFactory)
{
}
Now, my question is : Is Ninject creating 2 separate contexts when creating an instance of my RTWRepository and also when creating an instance of ModelFactory?.
The reason that I'm asking that is because I'm having a problem when I try to save an entity that has a dependency to another object which was previously retrieve from the db.
I'm saving the entity in my controller but I'm creating it in my model factory along with is dependency.
public class RecycleCenter
{
public RecycleCenter()
{
}
public int MyProperty { get; set; }
[Required]
public virtual Address Address { get; set; }
}
The code above is for the entity Recycle Center which has an Address, this recycle center entity is created in my model factory and then in my controller I try to save it but when my repository execute this line
_context.RecycleCenters.Add(entity);
I'm getting this error
An entity object cannot be referenced by multiple instances of IEntityChangeTracker
So, somewhere in my code I'm using 2 context instead of 1 and I think is when creating the ModelFactory and RTWRepository, is this assumption correct?, if so how do I fix it?
TL;DR;
You probably need to change this line:
kernel.Bind<RTWAPIContext>().To<RTWAPIContext>();
to
kernel.Bind<RTWAPIContext>().To<RTWAPIContext>().InRequestContext();
Explanation:
When you define a binding in Ninject, you also specify how that object's lifecycle should be handled.
If you don't explicitly define it, Ninject's default lifecycle is Transient. Transient means that each time an instance is required, it will create a new one. In your case, you need to two instances: one for the RTWRepository of the ModelFactory and one for the RTWRepository of the MaterialsController.
You can modify the lifestyle to one of these options:
Singleton ==> kernel.Bind<RTWAPIContext>().To<RTWAPIContext>().InSingleTonScope();
Request ==> kernel.Bind<RTWAPIContext>().To<RTWAPIContext>().InRequestScope();
Thread ==> kernel.Bind<RTWAPIContext>().To<RTWAPIContext>().InThreadScope();
Named, Call, Parent, Custom
In your case, I think you need InRequestScope, but you have to check the necessary lifecycle as it depends on the application.
For further information please check out the documentation here: https://github.com/ninject/ninject/wiki/Object-Scopes
Most probably, it is. There's no annotation that is telling to Ninject "Hey, stop, when you have created the instance once, reuse it". You should agree that in most cases, you would want multiple instances of an object and that it is a rare case, where you want it only once.
If you want to reuse the instance, use the singleton pattern. Ninject is familiar with it, so you can bind the object mapping to a method
kernel.Bind<RTWAPIContext>().ToMethod(c => RTWAPIContext.GetInstance());
There is also a ToSingleton binding, but I bet you cannot make your context constructor private and implement C# specific singleton due to other ASP.NET problems (e.g. ASP.NET Identity will try to invoke the context's method for object creation).
I have a MVC project with following pattern
View <-> Controller <-> Service <-> Repository/Entities <-> Database
For example, if I have 2 tables (Customer and Order) in my Database, then I have 2 classes in my Repository layer (this class map 1:1 with my database table because I'm using EF Code First) :
public class Customer
{
[Key]
public int CustomerID { get; set; }
public int Name { get; set; }
//rest of columns here
}
public class Order
{
[Key]
public int OrderId { get; set; }
//rest of columns here
}
Then I have services :
public class CustomerService : ICustomerService
{
void AddNewCustomer(Customer obj);
void GetCustomerOrders(Customer obj);
//rest of methods here
}
public class OrderService : IOrderService
{
void GetOrderById(int id);
void GetCustomerOrders(Customer obj);
//rest of methods here
}
you probably notice that I have GetCustomerOrders.
My question :
Without breaking Single responsibility principle rule, where do I put GetCustomerOrders? In CustomerService, OrderService, or both?
Did I break the Single responsibility principle rule by having more than one service in my controller? For example :
public class TransactionController : Controller
{
//more than 1 service inside this class
private ICustomerService _customerService;
private IOrderService _orderService;
public ProjectController()
{
this._customerService = new CustomerService();
this._orderService = new OrderService();
}
public ProjectController(CustomerService customerService, OrderService orderService)
{
this._customerService = customerService;
this._orderService = orderService;
}
public ActionResult Index()
{
Return View();
}
public ActionResult CreateCustomer()
{
//rest of code here
}
public ActionResult CreateOrder()
{
//rest of code here
}
}
I have bunch of controller with bloated Action method, for example my ProductController have :
Index
Add
Edit
Delete
Priority
AddPriority
EditPriority
DeletePriority
If the controller were split
ProductController
Index
Add
Edit
Delete
ProductPriorityController
Index
Add
Edit
Delete
I see that the template project from Microsoft doesn't have more than one CRUD operation inside their Controller (towards bottom example). Is it a bad design if I have more than one CRUD operation inside my controller (top example)? I was thinking of splitting my Controller but I don't want it to bite my ass later for having to maintain 50 controllers.
Any help will be appreciated and apologize for bad english.
I will put it in customerService because it depends on the customer you pass to the function.
I think that the maximum services for controller is about ~3/4 services in one controller. So in your case i think this is good.
The controller doesn't need to implement your business logic. They only should take data and post them to the right place. I think you should create a manager / service / class that will handle the business logic. About your CRUD operations, It should be all in one controller (get/post and etc).
1- You don't always need to go through a service to access the repository in the controller.
You can embrace an onion architecture for example where instead a 3 layers architecture. Personally I think important the concept of accessing layers in the right way, but adding a indirection level just to call a repository with no logic inside the service, makes me question the value of the service, because in that case, what is the service that the service is providing?
Since your repository knows the domain, you can return domain objects.
What about commands and queries?
You can read a little bit more and make your one of all this your preference or maybe adapt an idea. Just keep the idea of separation of concerns always in mind, you are on the good way.
About questions 2 and 3 I agree with #Rik, but I will paste his answer just to make my answer complete (credit on him)
2- No, that's fine. In fact, you're are dividing the different responsibilities over separate services, which is very "single responsibility"
3- I'd say keep them separate if they do separate things. Maintaining a number of controllers is easy if you know which controller is responsible for what.
I suggest making a CustomerOrdersController.
No, that's fine. In fact, you are dividing the different responsibilities over separate services, which is very "single responsibility".
I'd say keep them separate if they do separate things. Maintaining a number of controllers is easy if you know which controller is responsible for what.
I'm pretty new to the concept. What I'm trying to do is create a factory that will return an object that is used for repository functions. No problems there. So I create the instance of a concrete factory in main() and store it in a static property of App but my entities are in a separate dll. Does it make sense to pass the repository to each entity class in the constructor? This doesn't feel right. My question is: how is the best make my entities aware of which repository they should be using?
My App partial class looks like
public partial class App : Application
{
private static ICalDataAccess _daqFactory;
public static ICalDataAccess DataAccessFactory
{
set { _daqFactory = value; }
get { return _daqFactory; }
}
}
Maybe a little more code is in order.
public class Widget
{
public string Description { get; set; }
public int ID { get; set; }
private IWidgetRepository _widgetRepository;
public Widget(IWidgetRepository WidgetRepository)
{
_widgetRepository = WidgetRepository;
}
public void Save()
{
_widgetRepository.Save(this);
}
}
Am I doing anything egregious here?
I think the general recommendation is to keep your entities free from persistence concerns. That is, you have some code that retrieves the entities and uses them to perform whatever work needs to be done, resulting in new, deleted or modified entities, which the calling code then submits to the appropriate repository (or asks to be saved if you have something which tracks or detects modified entities, like EF or NHibernate).
That way your entities do not need to know about repositories at all.
I usually create a UnitOfWork helper class which exposes all of my repositories through a "public RepositoryFactory Repositories { get; }" property, so that simply by supplying an instance of the UnitOfWork class I have access to all of my data sources. UnitOfWork can then be injected via IoC to whatever class needs to have data access.
Some recommended reading on this topic:
Persistence Patterns
Discussion on this same topic elsewhere
Your description sounds more like the service locator pattern than dependency injection. Dependency injection typically looks like any object that needs some service object (such as data access) to do its work receives that service as parameter to its constructor.
In wanting to get some hands-on experience of good OO design I've decided to try to apply separation of concerns on a legacy app.
I decided that I wasn't comfortable with these calls being scattered all over the code base.
ConfigurationManager.AppSettings["key"]
While I've already tackled this before by writing a helper class to encapsulate those calls into static methods I thought it could be an opportunity to go a bit further.
I realise that ultimately I should be aiming to use dependency injection and always be 'coding to interfaces'. But I don't want to take what seems like too big a step. In the meantime I'd like to take smaller steps towards that ultimate goal.
Can anyone enumerate the steps they would recommend?
Here are some that come to mind:
Have client code depend on an interface not a concrete implementation
Manually inject dependencies into an
interface via constructor or property?
Before going to the effort of
choosing and applying an IoC
container how do I keep the code
running?
In order to fulfil a dependency the default
constructor of any class that needs a
configuration value could use a Factory
(with a static CreateObject() method)?
Surely I'll still have a concrete dependency on the Factory?...
I've dipped into Michael Feathers' book so I know that I need to introduce seams but I'm struggling to know when I've introduced enough or too many!
Update
Imagine that Client calls methods on WidgetLoader passing it the required dependencies (such as an IConfigReader)
WidgetLoader reads config to find out what Widgets to load and asks WidgetFactory to create each in turn
WidgetFactory reads config to know what state to put the Widgets into by default
WidgetFactory delegates to WidgetRepository to do the data access, which reads config to decide what diagnostics it should log
In each case above should the IConfigReader be passed like a hot potato between each member in the call chain?
Is a Factory the answer?
To clarify following some comments:
My primary aim is to gradually migrate some app settings out of the config file and into some other form of persistence. While I realise that with an injected dependency I can Extract and Override to get some unit testing goodness, my primary concern is not testing so much as to encapsulate enough to begin being ignorant of where the settings actually get persisted.
When refactoring a legacy code-base you want to iteratively make small changes over time. Here is one approach:
Create a new static class (i.e. MyConfigManager) with a method to get the app setting (i.e. GetAppSettingString( string key )
Do a global search and replace of "ConfigurationManager.AppSettings["key"] and replace instances with "MyConfigManager.GetAppSettingsString("key")"
Test and check-in
Now your dependency on the ConfigurationManager is in one place. You can store your settings in a database or wherever, without having to change tons of code. Down side is that you still have a static dependency.
Next step would be to change MyConfigManager into a regular instance class and inject it into classes where it is used. Best approach here is to do it incrementally.
Create an instance class (and an interface) alongside the static class.
Now that you have both, you can refactor the using classes slowly until they are all using the instance class. Inject the instance into the constructor (using the interface). Don't try for the big bang check-in if there are lots of usages. Just do it slowly and carefully over time.
Then just delete the static class.
Usually its very difficult to clean a legacy application is small steps, because they are not designed to be changed in this way. If the code is completely intermingled and you have no SoC it is difficult to change on thing without being forced to change everything else... Also it is often very hard to unit test anything.
But in general you have to:
1) Find the simplest (smallest) class not refactored yet
2) Write unit tests for this class so that you have confidence that your refactoring didn't break anything
3) Do the smallest possible change (this depends on the project and your common sense)
4) Make sure all the tests pass
5) Commit and goto 1
I would like to recommend "Refactoring" by Martin Fowler to give you more ideas: http://www.amazon.com/exec/obidos/ASIN/0201485672
For your example, the first thing I'd do is to create an interface exposing the functionality you need to read config e.g.
public interface IConfigReader
{
string GetAppSetting(string key);
...
}
and then create an implementation which delegates to the static ConfigurationManager class:
public class StaticConfigReader : IConfigReader
{
public string Get(string key)
{
return ConfigurationManager.AppSetting[key];
}
}
Then for a particular class with a dependency on the configuration you can create a seam which initially just returns an instance of the static config reader:
public class ClassRequiringConfig
{
public void MethodUsingConfig()
{
string setting = this.GetConfigReader().GetAppSetting("key");
}
protected virtual IConfigReader GetConfigReader()
{
return new StaticConfigReader();
}
}
And replace all references to ConfigManager with usages of your interface. Then for testing purposes you can subclass this class and override the GetConfigReader method to inject fakes so you don't need any actual config file:
public class TestClassRequiringConfig : ClassRequiringConfig
{
public IConfigReader ConfigReader { get; set; }
protected override IConfigReader GetConfigReader()
{
return this.ConfigReader;
}
}
[Test]
public void TestMethodUsingConfig()
{
ClassRequiringConfig sut = new TestClassRequiringConfig { ConfigReader = fakeConfigReader };
sut.MethodUsingConfig();
//Assertions
}
Then eventually you will be able to replace this with property/constructor injection when you add an IoC container.
EDIT:
If you're not happy with injecting instances into individual classes like this (which would be quite tedious if many classes depend on configuration) then you could create a static configuration class, and then allow temporary changes to the config reader for testing:
public static class Configuration
{
private static Func<IConfigReader> _configReaderFunc = () => new StaticConfigReader;
public static Func<IConfigReader> GetConfiguration
{
get { return _configReaderFunc; }
}
public static IDisposable CreateConfigScope(IConfigReader reader)
{
return new ConfigReaderScope(() => reader);
}
private class ConfigReaderScope : IDisposable
{
private readonly Func<IConfigReader> _oldReaderFunc;
public ConfigReaderScope(Func<IConfigReader> newReaderFunc)
{
this._oldReaderFunc = _configReaderFunc;
_configReaderFunc = newReaderFunc;
}
public void Dispose()
{
_configReaderFunc = this._oldReaderFunc;
}
}
}
Then your classes just access the config through the static class:
public void MethodUsingConfig()
{
string value = Configuration.GetConfigReader().GetAppSetting("key");
}
and your tests can use a fake through a temporary scope:
[Test]
public void TestMethodUsingConfig()
{
using(var scope = Configuration.CreateConfigScope(fakeReader))
{
new ClassUsingConfig().MethodUsingConfig();
//Assertions
}
}