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
Related
Recently I started working on a new project using .NET Core 2.1 and I decided to use the SOLID principles and create a nice project structure.
It is a Web API project. Everything is working fine I use a lot dependency injection, most of the stuff is easy to test.
And that's the part where I have to register all my services. I am literally having hundreds of lines looking like this:
services.AddSingleton<...>();
or
services.AddScoped<...>();
I have one line for every service and for a small project it would be fine. However when I have hundreds of these it becomes on BIG mess. Basically the whole project is in a super nice order and there comes the Startup.cs that is full of services.AddX statements.
I was think of creating static classes with methods that register the services but that just doesn't look fine.
I will need to add more services in future and I can't just keep creating static classes or filling the old ones because I will end up with the same mess again and it will be more difficult for me to remember where am I registering a given service.
If you really have hundreds of them, you may want to replace the default container with for example Autofac. These type of frameworks supports modules or kind of "subcontainers".
A module is a small class that can be used to bundle up a set of related components behind a ‘facade’ to simplify configuration and deployment.
Replace DI
Autofac modules
You can have each logical group of services (assemly) export its own RegisterServices method. It is the responsibility of that assembly to select lifetime and scope anyway.
For cosmetics, make it an AddMyStuff() extension method in the Microsoft.Extensions.DependencyInjection namespace.
See AddMvc() for an example. Look it up (F12) and notice the difference between the assembly and the namespace it is in.
I'm working on WPF MVVM project which contains following projects,
Domain,
ViewModels,
Infrastructure,
Views
and for example I need IFileService that provide some operations with file and doesn't contains any business logic, I'm sure that the implementation of this interface FileService will be in Infrastructure project, but I have question where to put the IFileService interface
I need to use this interface in ViewModels project, if I will put it in this projects its mean that Infrastructure will have reference on ViewModels that is not good I think, if I will put it in Domain which contains business related classes the same.
Help me what is the best to organize structure and references between projects and where to put interfaces like IFileService?
Hmm, why not creating an additional project like DAL or DataLayer? It provides the model classes, which I'm also missing in your listing. You could also put the interface IFileService there although I would prefer working with DataProviders or Repositories (that's my prefered option), so that the VMs are not aware from where the data was loaded.
IMHO The project Infrastructure shouldn't not contain any sofisticated logic. I would put some useful methods and classes there and keep it as simple and clean as possible, so that it could be referenced everywhere. Probably, you won't even need it.
The unique rule I use for my MVVM project is, all projects have a reference to my Infrastructure project and my Infrastructure project has no reference to my other project.
So IMHO, IFileService, and interfaces in general, should be in the Infrastructure project. Then it is up to you decide where to put the implementation. The Infrastructure project usually has very basic logic implementation and final implementation goes to a dedicated project.
The only exception I sometimes add to this rule is when I base my development on an existing MVVM framework, then Infrastructure might reference it too but I try to avoid this approach.
You should put the IFileService interface to Infrastructure project. because this will make it available to every project as this is the core project right. and you might have diffrent implemantations e.g. syncronious file reader and asyncronius file reader. so the implemantation could go into your modules or ViewModels.
I can see that similar questions has been asked previously, but being totally new to DI and .Net I am not able to grasps the entire solution or may not have found the right source....
I have assemblies WebAPI,BL,DL.
WebAPI is dependent on BL,
BL is dependent on DL,
WebAPI DOES NOT reference DL and I would like to keep it the same. There are few more assemblies but this is sufficient to illustrates the issues.
WebAPI has application start section therefore I can use it to initialize the Ninject Kernel and register dependencies for WebAPI project.
How could I achieve the same for BL and other assemblies?
There are a couple of different ways, you can use the Ninject Conventions to automagically resolve every ISomething to an implementation that has the same name (e.g. IThing -> Thing) or you can create a Ninject Module in each assembly which registers the dependencies (the module in your BL could load the module in your DL).
The approach you take would depend on whether you need to define different scopes for different objects, for example if you wanted some things resolved as singletons that may affect which method you use.
I think Mark Seemann's advice about this is great -- make a composition root at the highest possible layer of your application. For Web apps, this means in the Globals.asax file. I could expound on the good reason's for this, but the linked blog post does a better job.
This does break the layering you are trying to achieve, but only barely, and what I think is an appropriate way. If your web layer is appropriately thin (i.e., you could replace it with a thick client fairly easily) then it isn't a big loss. If you are really adverse to that, you could create a composition root in the BL for the DL.
I'm developing a .Net desktop app that interacts with scientific instruments. There are a number of variations of this instrument, each with different features, components, etc, so I've come up with a plugin/modular architecture where a "module assembly" contains all of the necessary business logic, UI, etc. to interact with that hardware component/feature.
Currently I have one solution that contains everything - the "core" application project, common libraries, plus the "module" projects. The idea is that we install the whole lot to a customer site (rather than cherry-picking which DLLs they need), and "activate" the relevant modules using a config file that contains a list of required modules.
The main application project loads the modules using Castle Windsor, using an AssemblyFilter and a custom InstallerFactory. It searches each module assembly looking for a class implementing IWindsorInstaller and decorated with a particular custom attribute (which has a property containing the module name). The module's installer will only be run if the attribute's module name is one of those requested. These installer classes are responsible for registering everything needed by that module with Windsor (business logic, views, view models, etc.).
This solution works fine in my proof of concept, however I can see a scenario where two or more modules are functionally very similar, and will therefore need to share common code. Let's say I have projects "ModuleA" and "ModuleB", and their Windsor installers registers the same IFooService class in project "ClassLibraryX". The app will fall over because IFooService has been reigstered twice, and Windsor won't know which one to resolve when requested by a constructor.
What's the best way to handle this? Thoughts so far:-
Find out if a particular component has already been registered with Windsor. This feels hacky (if possible at all)
Register components using a name, but how do I request a named instance with constructor injection?
In each module project create a new interface, such as public interface IModuleAFooService : IFooService, and register/use this throughout the project (rather than IFooService).
Any thoughts?
Edit: in fact Windsor won't fall over when it tries to resolve IFooService. It will fall over when the second module attempts to register the same interface/concrete implementation!
The way I see it, you have a couple options. I think you have two main issues. The first is that you are installing the shared interface twice (or more than that). The second is that you could have two different versions of the shared interface.
For the first issue, I would separate out the shared interfaces into their own assembly. Inside that assembly, I would have an installer that is scoped to that assembly. Then, you can tell Windsor to install that shared component and it knows how to wire itself up.
For the second issue, you have two options (as I see it). First option is that you keep your shared components backwards compatible. Second option is to isolate you runtime (through app domains or processes).
Can you not provide some meta-data for the plugin, i.e give each plugin implementation a name attribute which can be used by windsor to identify which of the implementations you want?
I have not used Castle too much recently but I am sure it did have the notion of named Bindings/Registrations, so you could use that as a way to distinguish things, if that is not going to be possible and there is no other meta data you can think of using which would make it less ambiguous for Windsor, then I would just opt with your 3rd option.
Having just read your 2nd option again (after writing the above) that seems the best option, I cannot remember EXACT syntax but in most DI frameworks you do something like:
var instance = Get<IMyInterface>("Named This");
There will be loads of syntax examples on their documentation somewhere, but you will need to know the name on both the Windsor side to register it AND on the client side to request it.
Named instances are ok. You can define dependency on concrete named service via DependsOn(Dependency.OnComponent("paramName", "serviceName")) method in fluent configuration.
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.