Folks,
I am trying to re-factor a legacy brownfield application into a CQRS architecture with commands and a command bus for domain modifications.
The application will more than likely be implemented in Asp.Net MVC3. My employer prefers the use of Unity for DI in MVC applications.
Any examples I can find showing a dependency container for command/bus resolution are based on Structuremap or Autofac, however I will need to use Unity in this implementation. Has anyone used Unity in this manner or know of any examples?
Where exactly do you think you need the container at all? Maybe this post contains some usefull information.
It describes a container agnostic way of handling commmands.
Update
You mean you would like to have something like this:
var builder = new ConfigurationBuilder();
var convention = new CommandHandlerConvention().WithTransaction().WithDeadlockRetry();
builder.Extension<DecoratorExtension>();
builder.Scan(x =>
{
x.With(convention);
x.AssemblyContainingType(typeof(BarCommand));
});
var container = new UnityContainer();
container.AddExtension(builder);
ICommandHandler<BarCommand> barHandler = container.Resolve<ICommandHandler<BarCommand>>("BarHandler");
var command = new BarCommand();
barHandler.Handle(command);
Assert.AreEqual("-->Retry-->Transaction-->BarHandler", command.HandledBy);
That registration uses a custom configuration engine for Unity that provides a lot of the features of StructureMap's config.
Update2
The code samples are part of my pet project on codeplex. The above snippets can be found inside the TecX.Unity.Configuration.Test project.
Related
I'm looking to write a daemon process using .NET Core which will basically act much like a cron job and just orchestrate API/DB calls on some interval. As such, it has no need to expose any web routes, so there's no need for ASP.NET Core.
However, afaik ASP.NET Core is where you get that nice Startup class with all the DI plumbing and environment-based configuration you might need.
The way I see it, I have two options:
Forgo ASP.NET Core and just hook up the DI framework on my own. If I go that route, how do I do that?
Include ASP.NET Core just for the DI portion, but then how do I spawn background tasks which "run forever" outside of any request context? My understanding is that the DI framework very much assumes there's some sort of incoming request to orchestrate all the injections.
You seem to pose multiple questions let me try to answer them one by one.
Dependendency injection without Startup Class.
This is definitely possible. Since the Startup class is part of the WebHostBuilder package (which contains Kestrel/webserver). The Dependency injection is nuget package is just a dependency on this package and so can be used alone in the following way:
var services = new ServiceCollection();
services.AddTransient<IMyInterface, MyClass>();
var serviceProvider = services.BuildServiceProvider(); //ioc container
serviceProvider.GetService<IMyInterface>();
So at your program main (startup function) you can add this code and maybe even make the ServiceProvider Staticaly available.
Note that the IHostingEnvironment is also part of the kestrel package and not available to you, but there are simple workarounds for this.
Registration
Im not sure what exactly you mean by spawning background tasks/running forever. But in dotnet you can spawn tasks with TaskCreationOptions.LongRunning to tell the schedular that your task will be running very long and dotnet wel optimise threads for this. you can also use serviceProvider in these tasks.
The only downside to the DI is that you need to set it up at the startup of your application and cannot add new services while running your application (actually you can add to services and then rebuild the serviceProvider, but its easier using another external IOC container). If you where thinking of running some kind of plugin system where dependencies would automaticaly be registered, you're better of making your own factory method.
Also note when using plugins, when they are loaded in as dll's, they cannot be unloaded so if you have a theoretically unlimited amount of plugins, your memory will slowly build up every time you add new plugins.
As of.NET Core 2.1 this can/should be done with a Generic Host. From
.NET Core docs:
"The goal of the Generic Host is to decouple the HTTP pipeline from the Web Host API to enable a wider array of host scenarios..."
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-2.1
public static async Task Main(string[] args)
{
var builder = new HostBuilder()
.ConfigureAppConfiguration((hostingContext, config) =>
.ConfigureServices((hostContext, services) =>
{
// ...
});
await builder.RunConsoleAsync();
}
In the new ASP.NET 5.0 (vNext), the startup code relies on the IApplicationBuilder interface. The Use method is used to add a handler to the builder, while Build is used to construct the final delegate. But I can't figure out what is the purpose of New. I've been digging in GitHub, but can't find any place where that's used.
Anyone understand what is the purpose of that method?
New() creates a second ApplicationBuilder, sharing all the ApplicationServices and ServerFeatures of the first one, but none of the middleware. It is used internally by the branching extensions (Map, MapWhen, UseWhen) to create the new 'branch'.
You can find the implementation here: ApplicationBuilder.cs.
In some cases, it is also useful in higher-level frameworks.
For exemple, the [MiddlewareFilter] attribute in MVC Core uses New() internally to execute a piece of ASP.NET Core middleware inside the MVC framework (i.e. as a filter). MVC Core creates a small pipeline around the middleware, builds it into a RequestDelegate, then runs the HttpContext through it. Just like ASP.NET Core does with your 'main' pipeline built in Startup.cs.
Thanks to this feature, we can reuse a piece of general-purpose ASP.NET Core middleware, from inside MVC.
For more information, see MiddlewareFilterBuilder.cs in ASP.NET MVC Core.
It appears to be there to branch [clone] the original instance (as can be demonstrated in src/Microsoft.AspNet.Http/Extensions/MapExtensions.cs). There was also a previous MapWhenExtensions.cs, but it appears to have been removed from the dev branch.)
I suspect it's an artifact of a previous design that would provide the ability to bind middleware based on circumstances without affecting the root's configuration. The fact that it's been there since before IBuilder was refactored to IApplicationBuilder and that most dependencies were in files that have since been removed from the dev branch, I would venture a guess that it's old news.
Of course it's hard to tell given neither the interface nor the base implementation are commented.
I am trying to use Servicestack with F#. So, far I am successful. But while trying to pull thing up with asp.net hosting using razor engine. I come across weird issue.
If for default.cshtml I choose property that do not copy with compilation with content than page is not getting populated and it is going to metadata page. But if I set to copy if newer it will work.
But as far as I know this should be do not copy only as compilation is content. If we are not doing that then for every change in cshtml page there is need to re-run the project.
Now, this is also unique to F# project, in C# it is working. So, I exactly don't know where to look. BTW I am using 3.9.71 version of servciestack.
Please let me know if any further details is needed. My project repo
Update:
Your application is setup incorrectly.
Your F# MVC application isn't setup properly. You are using ASP.NET which should use IIS as its host. Which means the requests from IIS get passed into the AppHost. However in your setup you are using an AppHostHttpListenerBase this is actually creating it's own HTTP Listener, essentially you have mixed the Standalone Self Hosting with ASP.NET hosted setup.
As a result you are getting the odd situation of having to copy the content to the output directory. That's because in a standalone ServiceStack app, that is the requirement, it's looking for the content in the wrong place.
Try using this:
type AppHost =
inherit AppHostBase
new() = { inherit AppHostBase("Hello F# Services", typeof<HelloService>.Assembly) }
override this.Configure container =
...
You should read this article to ensure you have setup the MVC ASP.NET application correctly.
You will still want to use DebugMode = true to enable ServiceStack to automatically pick up on changes, so I have left that part of the answer in.
It's a little hard to follow what you are saying, but if I have interpreted it correctly, you are saying you have an F# ASP.NET ServiceStack Razor project and you are finding that you are having to re-run the build process every time you make changes to your Views.
I haven't used F# yet so I will have to give the example in C# but you need to set your AppHost config to DebugMode = true in order to have ServiceStack automatically pick up on the changes, and thus you won't have to re-run the build process each time.
SetConfig(new EndpointHostConfig {
DebugMode = true,
});
I notice in your code that this is not set:
type AppHost() =
inherit AppHostHttpListenerBase("Hello F# Service", typeof<HelloService>.Assembly)
override this.Configure container =
this.Plugins.Add(new RazorFormat())
ignore()
static member start() =
let apphost = new AppHost()
apphost.Init()
See the section "Automatic reload of modified views, layout templates and partials (in Debug mode)" in this documentation for more information.
So in Debug Mode we'll also do this where a background file system watcher monitors all pages, partials and Layout templates for modifications and recompiles and auto-reloads them on the fly ...
Please let me preface this by saying I am not very familiar with Unity. I understand it is an dependency injection container and I understand to a limited degree what that means. I inherited an application that uses Unity throughout although it does not seem to me to be implemented correctly. In session_start of the global.asa the previous developer uses the following code to instantiate the unity object then persists it through the entire session:
var unity = new UnityManager(new UnityContainer());
Session["UnityManager"] = unity;
As I understand it wouldn't this inherently cause concurrency issues? Can anyone provide an example of how to correctly implement unity or if this is correct explain to me why this is so?
If you're using mvc you could just remove the session and install unity.mvc3 from nuget package manager. It's compatible with mvc4 and sets it all up for you in a correct way. You can put the existing mappings in bootstrapper.cs (automatically installed)
Basically you want to have 1 static variable in the global.asax to access unity. So you can replace all those
var unitycontainer = Session["UnityManager"];
unitycontainer.resolve<>...
with
MVCApplication.Container.Resolve<> ..
While developing web project using ASP.NET MVC, I came up against a coupling problem.
When I build custom controller factory (or dependency resolver if using MVC 3), I need this factory to know somehow where to get dependencies from. Here's my code:
//from Global.asax.cs
DependencyResolver.SetResolver(new StructureMapControllerFactory());
class StructureMapControllerFactory: IDependencyResolver {
Container repositories;
public StructureMapControllerFactory()
{
repositories = new RepositoriesContainer();
}
//... rest of the implementation
}
class RepositoriesContainer: Container
{
public RepositoriesContainer()
{
For<IAccountRepository>().Use<SqlAccountRepository>();
//...
}
}
StructureMapControllerFactory class is responsible for injecting dependencies into a controller. As I said, it needs to know where to find these dependencies (I mean concrete classes, like services and repositories implementations).
I have a separate class library called MySite.Data, where all the implementation details live. Contracts, like IAccountRepository, live in library MySite.Contracts. Now, if I reference this MySite.Data library directly from MVC project, there will be a dependency between my site and implementation of its data retrieval. The question is how can I remove it? What are best practices in this situation?
I'm sure it does have a bunch of workarounds, just I haven't found any yet.
Well, as I see it, you can't do exactly that. Your MVC project really really needs to know about concrete classes it is going to use.
You will anyway have to provide those container registrations somewhere and you'll get the dependency on the project/assembly where that type is defined. Shortly, you have to reference MySite.Data from MVC project. Like that:
MySite.Data knows nothing about MVC project
MVC project knows the concrete repositories types to provide correct container registrations.
You can make life simpler with StructureMap Registry objects but you need to include those Registries somewhere as well. Typically those are in the main project or some "StructureMap-adapter" project but you'd need to make reference anyway.
I'd advise that you:
Use MVC3 and drop your custom IControllerFactory if you only use it for DI into your Controllers.
Use StructureMap Registry objects to provide each and every IoC registration ever needed.
Use StructureMap Assembly scanning capabilities to provide components discovery.
Use something much more common as a DependencyResolver, i.e. not a StructureMapControllerFactory but a CommonServiceLocator with StructureMap adapter instead.
Try to abstract from StructureMap itself inside your main app.
And, of course, don't be afraid of making references inside the main project - they have nothing about coupling. It doesn't decrease maintainability. But the wrong architecture does, so be worried about that, not simple reference.