I've got a basic asp.net MVC project that has a Web project, a Service dll project and a Data dll project. I started to store config values in the web project's applicaiton settings but I've come across a few instances where I need them in the service layer. The only way I can think of sharing the values is to pass them to the service layer via parameters. Is there any other way of having one config value that is accessible to all projects?
I tend to keep config tied to the outermost layer (where it is defined in app.config or web.config) and have that layer explicitly pass through any values which are needed for domain or infrastructure logic, which should be what your lower level layers contain.
I find the notion of having config values contained in the outer layer which are 'magically' used by lower level layers to be rather non-intuitive and opaque.
I know this has been answered .. but .. you should never have any dependencies on *.config files in service or data layers. This ads some very tight coupling. The best way is to get them passed in via parameters .. like via constructors.
Even in your website you still shouldn't, IMO. I would use Dependency Injection and inject them into the Controllers, if you really need them. why? Well -> unit testing. Unit tests shouldn't require any *.config file. As such, if your controllers are passed in the data, then your code has no dependencies now -> which is awesome.
Here's an example of a controller that has no dependencies on a web.config and here is how the app setting entries are passed into the controller VIA dependency injection.
Check it out :)
Related
I was reading about ASP.NET Core features and I decide to transfer my current solution ( MVC 5 ) to MVC 6 but I got a little bit confused regarding integrated DI.
Currently I have this architecture
CemaManager ( representative layer ) has reference to Helpers, Resource, ViewModel and BLL.
Bll has reference to ViewModel, Database and DLL.
Dll has reference to Database.
Typical N-tier architecture using DI and Repository pattern.
When I investigate MVC6 there is startup.cs where DI initialize.
That means if I want to separate BLL and DAL they will have all reference to MVC6 and all logic will go thru that layer? By the time It's gonna be heavy and hard to maintain and scale or am I wrong?
Is there any way to export startup.cs or DI method to another layer?
Maybe somebody know any articles to read or examples?
Personally I have a few things I would change about the overall structure, but I'm guessing a full design review isn't really what you're asking for. ON your actual question, no - your other layers do not need to reference MVC.
For most any application, IoC needs to be configured and initialized in the presentation layer. Ultimately your presentation layer needs a reference chain (direct or indirect references) to everything you want to register, but this has always been true.
You are already referencing Helpers, Resource, ViewModel, and BLL so you can easily register implementations for the interfaces in those layers. You could also add a reference to DLL to register implementations from that layer.
You can also go the indirect route and add a class in each layer which takes a reference to your IoC container and handles its own registration. In Autofac this is done using modules but there are equivalent ways of accomplishing the same thing using other IoC containers.
I have application with the following dlls:
Web project - MVC web application
Wcf Services - services that the web application uses.
Model - Entity framework code first entities and DbContext object.
Now when I need to change something lets say function in the wcf services so I change the function but the web also affected and I need to make add service reference again and change the code that uses the wcf service and also the model sometimes changes...
As the CCP states: package should not have more than one reason to change. If change were to happen in an application dependent on a number of packages, ideally we only want changes to occur in one package, rather than in a number of them.
This helps us determine classes that are likely to change and package them together for the same reasons. If the classes are tightly coupled, put them in the same package.
So in my design I violates this principle? If someone can explain better design I will be glad.
WCF Services contain WSDL definition which is the contract for using its functions and also defines the entities for it. One possible reason that you need to add your reference again is that you are changing this contract.
For more information check here:
http://msdn.microsoft.com/en-us/library/aa738723(v=vs.110).aspx
I am pretty new to MVC and I am currently working on an MVC 3 project in visual studio and I want to create a method or variable that is accessible globally. When I say globally I mean available in my web project, service layer project, and data layer project.
I guess when I say global I mean global to the entire solution.
I tried creating a class in the solution items folder and referencing in my web project but its not letting me add a reference to the class since it is not a DLL.
I am a little confused with how to do this. Any suggestion would be appreciated. Also keep in mind that though I am a programmer I am still somewhat new to MVC and programming.
Edit: I have also tried adding a method in the global.asax file but was unable to call it
You should create a shared assembly where you define the class. You can then add a reference to the shared assembly from all projects that need the feature.
The class that you want to be "global" sounds like some sort of service. I suppose this is the kind of thing you may want to do with a logging service for example.
Using a logging service as an example it is generally best practice for the interface to the logging service be defined in a lightweight contracts type assembly. Then any of your assemblies that require an implementation of ILoggingService should inject the necessary implementation using an IoC container such as Autofac or MEF.
This pattern is pretty common and allows you to share common services while keeping implementations loosely coupled. Also this pattern will lead to highly testable code as fake implementations can be injected with Moq
I am trying to wrap my head around IoC containers. As I delve deeper into this design pattern I come across multitudes of abstraction layers, interfaces and concrete classes when before I was simply instantiating a data-context class, using it and then disposing of it.
Whilst I am keen to continue forward there are some outstanding issues I don't know how to resolve and would like some clarification and guidance.
In a generic web application with 2 projects (mvc web & data layer
containing e.f.), if our dependancy resolver expects a repository
that implements a specific interface (allowing us to switch
repositories at any time in the future), where is this interface
defined? I dont see how it can be defined in the mvc web project because then the data access layer will become dependant on it and it cannot reside in the data access layer as then the mvc project depends on the dal and i've missed the whole point of this excercise. So is
the answer to define it in both projects and have each project
reference its own copy? ..Is that even possible? Or do i need to
create a third service layer project and stick one interface
declaration in it and have both projects reference this?
Ive seen a number of articles talking about Unity IoC with
interfaces such as IProductRepository, IClientRepository and
IProductService, IClientService (this is what I was referring to in
my opening paragraph). Am I correct in assuming that each of these
instances is supposed to reference a table in my database? If so
what happens if i have 50 tables? do i need to create 50 repository
interfaces and 50 table related interfaces just to decouple everything?
And how does using EF with POCO classes impact things? do i need to
have each POCO implement its own specified interface?
thanks
Ideally you would split your solution into several projects.
You would have a contracts project where your interfaces are defined, a dal where a concrete version of those interfaces are implemented.
Your mvc project would then reference the contracts project to handle the references to the types.
You would use an IOC container to scan the assemblies in the bin folder and find a concrete implementation of the dependencies for your controller. This means that you would build your dal into the bin folder of your mvc project. This means you can switch the dal out for other implementations simply by placing a new dll in the bin folder.
As for the repositories and tables, I tend to group them by business function. So a business function of managing users and their related tables would be in a user repository etc. but that is down to personal preference imo.
When you are breaking your project into tiers you are correct in not wanting your data layer to rely on a project further up the stack. In general you want these dependencies to be unidirectional. You can either continue what you are doing and put the interfaces in the data layer, or you can create a new project to house the model code, including the repository and service interfaces. Your data layer would depend on the model code, and your mvc layer will depend on the data layer.
To address your second question I would say this is where the art of design comes in. You don't necessarily want a one to one mapping between your entities and your data tables. If it makes sense and you believe it's manageable, especially with the help of Entity Framework, then go ahead with the one to one mapping. But keep in mind that the responsibilities of the persistence layer and the domain model layer are different. If the persistence layer starts to bog down your work creating the domain model then it's time to put some work into separating the two.
More important are the interface 'facades' that are going to be exposed to the mvc project. These are going to require some degree of decoupling from the model and persistence layers. They should be distilled down to the core responsibilities of the model. You don't want to clutter your application layer with the intricacies of your domain model.
I'm having a couple of problems with circular reference/dependency that I've been sitting on all day. Something must be wrong with my thought process, I just don't get it.
Here are my projects:
Flip.Main (ASP.NET MVC)
Flip.Domain (C# DLL)
Flip.Services (C# DLL)
Flip.Utility (C# DLL)
Current References/Dependencies:
Flip.Main -> Flip.Domain, Flip.Services, Flip.Utility
Flip.Services -> Flip.Domain, Flip.Utility
Flip.Domain -> Flip.Utility
I wanted to structure my project in a way that my services project has all services, my domain project the model, repository and 'fluent' extensions to query the model, and the main and utility project are pretty much self explanatory.
Problems encountered:
1) I have an EmailService in my Flip.Services project, which needs to send out localized emails. All localization is done in Flip.Main's App_GlobalResources. No idea how to get the strongly typed emails and other localized resources now to my service layer as Flip.Main already depends on the service layer and therefore I can have it depend back to the Main project.
2) I have business classes, e.g. CustomerSearchFilter which represents a strongly typed search query. I want those business classes outside of the Flip.Domain project because they are not part of the domain model. However, in my CustomerSearchFilter class I have domain class instances (e.g. CustomerGroup) so it needs to know about domain classes. At the same time my Fluent interface in my Flip.Domain project needs to know what CustomerSearchFilter is so I can apply it to my IQueryable interface. Circular reference again.
3) I have a custom [AuthorizeSessionState] attribute which I use to decorate specific controller actions in my ASP.NET MVC Flip.Main project. This is an ActionFilterAttribute which needs to instantiate my SessionService who resides in my Flip.Services project. I can't put this into my Utility class though (because Flip.Services already references Flip.Utility). I don't think they should be in Flip.Main either - do I have to make another project for this!?
(20 more)
I feel like I'm making a mistake somewhere down the line, especially when I read that others usually don't encounter circular reference problems. Help?
Use interfaces for all non-trivial classes. Place interfaces in a different assembly from implementation.
The question comes down to what you separate by namespace and what you separate by DLL. If you have a good reason to keep EVERYTHING modular, you have to work really hard. But if each of these dlls only have a class or two in them, perhaps you could merge them together?
Take a few minutes and sort out the procedures ... create an identifier for each project (FM, FS, FD, FU). List each publicly accessible procedure on a page and then add an identifier for a project, if that project uses the procedure ...
Then you can see which procedure needs to be in (or accessible to) which project.
Hope that helps!
You can put your localized email strings in Flip.Services. The downside is that you have two places to maintain localized resources. You can also have a separate dll for all your resources to minimize the place to edit resources.
You have to move the fluent interface to an other dll or make CustomerSearchFilter part of the domain.
You will need to add more projects or rearrange your structure and use namespaces to create the separation.
It sounds like your building on concrete implementations instead of interfaces/contracts. As Ima suggests define interfaces that describe what a certain class should be able to do. Use this interface when you declare properties, parameters and the like. Keep the interfaces separate from the implementaion and both the implementation and the projects that uses the interface can reference the interface project.
You then get the nice option of using dependency injection making your code easier to test as an a side
In the "tiers" of a domain, repositories and services live at the same logical level, above the domain in an infrastructure role. I would suggest moving your repository implementations (queries, etc.) outside of the domain itself. That solves #2 at least.