I'm new to Unity, but this question is more generic to IoC, and I’m pretty new to implementing IoC as a whole. I have VS2010 solution with this project structure (simplified slightly):
Business Objects – Folder
DomainModel (Class Lib prj.) – Entity Framework 2 POCO entities
Data Layer – Folder
DataAccess (Class Lib prj.) – EF2 EDMX
Repository (Class Lib prj.) – IRepository interface & repository concrete implementations
Presentation Layer – folder
WebUI – MVC Project
Service Layer
Service (Class Lib prj.) – IService interface and service (façade pattern) concrete implementations
All project reference the DomainModel project.
Repository references the DataAccess project.
Service Layer references the Repository project.
WebUI references the Service project & the Unity assemblies.
I have Unity configured to inject all my service types correctly in the WebUI (global.asax via a custom UnityControllerFactory.cs). But how do I configure Unity in the service layer to inject the repository objects?
I DON’T want to reference the Repository project from the WebUI to ensure during development no one shortcuts and bypass the Service layer.
Couple Ideas I have (not sure if it will solve it):
Move the IRepository Interfaces into the DomainModel and add the Unity.RegisterType<> calls for the IRepository
Set up Unity configuration in the Web.config
Any direction would be greatly appreciated, specifically to how to configure Unity for the service layer / Repository, but also in general about the project.
Add a bootstrapper of some sort in the Service project. Then reference the bootstrapper in the WebUI.
One way to do this would be to write a small Unity extension. Something like this:
public class ServiceLayerBootstrap : UnityContainerExtension
{
protected override void Initialize()
{
Container.RegisterType<IRepository, WhateverRepositoryImplementation>();
// etc.
}
}
Then, in the web project where you create the container and initialize it, do this:
var container = new UnityContainer()
.AddNewExtension<ServiceLayerBootstrap>();
Related
I am working on an asp.net core mvc 2.0 web application.
This application works with an sql server database and entity framework core.
I want to create a console project for doing some batch stuff at night. This project should access the same database than the web project.
So i decided to create a third common project (library) which will contains models classes, db context and migrations.
The 2 project will reference this common project.
When i try to run "dotnet ef" commands in the terminal, in the common project subfolder, i get an error saying me this project should be startup project. But this is a shared library ...
EF Core differs from EF in that the context is designed to be instantiated via a dependency injection container. In other words, it relies on a DbContextOptions instance being injected that tells it among other things what type of database connection to use and how to connect. Since this injection only occurs inside projects that actually run (i.e. not a class library), the EF command-line tools only work by default with "startup projects", i.e. projects that can actually be started.
To enable migrating against a class library, EF Core provides IDesignTimeDbContextFactory. The EF commands will look for an implementation of this interface, and if it exists, use that factory to create the context it needs. As a result, you simply need to create an implementation in your class library.
public class MyContextFactory : IDesignTimeDbContextFactory<MyContext>
{
public MyContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<MyContext>();
optionsBuilder.UseSqlServer("[connection string here]");
return new MyContext(optionsBuilder.Options);
}
}
Yes, this means you need to hard-code your connection string, but importantly this is not environment-specific. More appropriately, the only environment you should be migrating in is development, so you don't need it to be environment-specific.
Documentation
I have to create 2 projects. For this I will user Spring,JPA,JSF and Maven. My projects will be structures on a 3 layer architecture, so I will have view,service and DAO layers. The persistence layer will be provided by hibernate with JPA2.0.
The problem is that this two projects will share a big part of code, basically both projects operates on the same database, and will share the majority of entities, DAO`s and maybe even services.
After I googled a little bit i found that this task cand be achieved with a multi module maven project. So I have created a multimodule maven projects which was composed of:
- core package (that will contain all the common classes),
- internal webApp (which will be accessed by internal users)
- external website (which will be accessed by external customers).
The problem that i encountered here is persitence.xml location, because if i put that file to core package i cannot include the entities from other projects. If i put the file inside projects i can refer the core entities with inside persitence.xml, but some functionality that i want to share, ie:
public abstract class GenericDaoImpl<T> implements GenericDao<T> {
#PersistenceContext(type = PersistenceContextType.TRANSACTION,unitName="CCPU")
protected EntityManager em;
wont work anymore because eclipse is "screaming" that there is no persistence unit with name CCPU, because the persistence.xml file is no longer in this project.
First of all, is this the right approach for this kind of problem?
The last but not the least, where should i put the persistence file in order to be able to combine entities from all 3 sub projects ?
I have the same situation: two webapps with common domain objects, but all my entities are located in "domain" module. Webapps are like "front-end clients" for "domain" back-end module.
If you want to locate webapp-specific entities in appropriate projects try to delete "em" field from GenericDaoImpl and pass it as parameter to all methods.
We want to create a spring MVC project using maven. We want to use just one project and, under it, have multiple sub-projects
What would be a good directory/package structure for the project for example
com
company
subproject_1
controller
doa
service
entity
subproject_2
controller
dao
service
entity
or all files of sub projects in one project
com
company
controller
all controllers of all sub projects
doa
all dao of all sub projects
service
entity
depending on the experience which project structure would be maintainable if the project increases and sub projects keeps adding on
or suggestion of any other package structure?
also what is the naming standard used for directory
is it entity or domain? doa or persistence?
Why not following a multi-module project structure to group your sub-projects? It's a good coding practise widely adopted, recognised and easily manageable. Have a look at this example.
As far as the naming conventions goes that's personal preference but it's good idea to clearly maintain in package structure the different layers as you are saying from botton-top approach: the dao level, the domain, the service layer, the controllers and finally the view.
Try to use the add to working set option.
Create maven multimodule project.
In each project two options:
package by feature
package by layer
these options discussed here: http://www.javapractices.com/topic/TopicAction.do?Id=205
My personal approach is to create in each maven module project packages by feature and some "util" packages used by "feature" packages.
The question is quite straightforward.
In my MVC3 application I have an architecture with Repository and Service layers, with the Repository exposing its methods to the Service layer and the Service layer exposing its methods to the Controller.
The Service layer is a class called MyServices that implements a IMyServices interface.
In a typical Visual Studio MVC3 folder organization where would you place MyServices and IMyServices?
There's no rule for that. A Services folder seems logical. Or if you are writing a reusable service layer you might put that into a separate class library which you would reference in your ASP.NET MVC application.
I've been looking into Ioc containers and AOP recently, and I'm pretty amazed by the concepts. I'm struggling however to decide how and where to implement the container.
The articles below suggest implementing the container in the 'application entry point':
Best Practices for IOC Container
IOC across visual studio projects?
Not understanding where to create IoC Containers in system architecture
Now - my thought-experiment application will consist of multiple visual studio projects ( one for data access, winforms application ). And let's say I want to use AOP for logging with Log4net, and so I setup log4net in the Ioc container.
So WinForms application in entry point, that's where Ioc container should go.
Here's the question: if I want to log stuff in my data access project/layer, should I add a
reference to my winforms application, get the ioc container from there, get the log4net instance out of it and use it for logging?
That would mean my data-layer depends on winforms application, that can't be right. How about I put the container is something like a 'Common' project within the solution. That way, all related projects (Data access/winformsa etc.) can access the container.
What is the right way to go here?
Your application's Composition Root would be the Windows Forms project. This is the only project which should have a reference to a DI Container.
In all other projects, dependencies should be injected via Constructor Injection. All decent DI Containers understand this pattern and use it to Auto-wire dependencies from the Composition Root.
I've abstracted my container into a separate assembly that all other assemblies / projects depending on its services reference. The container project has just a single class and - more or less - a single method:
public class MySpecialContainer
{
public T Resolve<T>() { // ... Get stuff from the IoC container }
}
The container build would either occur in MySpecialContainer's ctor or just add another method like Initialize() or some such.
The only problem is this approach broke down for me when I used Autofac and had both a Windows Service and ASP.Net project needing the container. Each had its specific requirement for scoped-lifetime services: Windows Service - PerLifetimeScope, ASP.Net - PerHttpRequest. I guess I could've passed in an argument into MySpecialContainer that denoted which scenario to configure for but I decided just to take on an Autofac dependency directly.
The good news is, if you stick to ctor injection, then you can very easily swap out various container implementations - Autofec, Ninject, StructureMap, etc.