Cannot register the component in castle windsor - castle-windsor

I have used the below link for the castle windsor dependency injection.I am not able to register the component.
http://www.codeproject.com/Tips/1052382/ASP-NET-MVC-Dependency-Injection-using-Windsor#_comments
public class ServiceInstaller : IWindsorInstaller
{
public void Install(Castle.Windsor.IWindsorContainer container,
Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
{
container.Register(
Component.For<Interfaces.TestInterface>()
.ImplementedBy<Services.TestServices>()
.LifestyleTransient());
}
}
ErrorMessage:
An exception of type
'Castle.MicroKernel.ComponentRegistrationException' occurred in
Castle.Windsor.dll but was not handled in user code
Additional information: Component
TestForCastleWindsor.Services.TestServices could not be registered.
There is already a component with that name. Did you want to modify
the existing component instead? If not, make sure you specify a unique
name.

That component is being registered twice. This can happen when IWindsorInstaller implementations or components are picked up by convention. For example, all assemblies in a directory are scanned for implementations of IWindsorInstaller and an old duplicate assembly is present. Or all implementations of another interface also implemented by your component are previously registered.

Related

Injecting DbContext into FileProvider in ASP.NET Core

I am trying to load some of the views from the database as described in here. So I want to use EF Core in the File provider.
RazorViewEngineOptions has a FileProviders property that you can add your file provider to. The problem is that you have to give it an instace of the file provider. So you'll need to instantiate all of the file providers' dependencies right there in Startup's ConfigureServices method.
Currently I inject an instance of IServiceProvider into the Configure method of Startup. Then I store the instance in a field (called _serviceProvider):
IServiceProvider _serviceProvider;
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider provider)
{
_serviceProvider = provider;
...
}
Then in ConfigureServices I use that field to instanciate the UIDbContext.
services.Configure<RazorViewEngineOptions>(options =>
{
var fileProvider = new DbFileProvider(_serviceProvider.GetService<UIDbContext>());
options.FileProviders.Add(fileProvider);
});
Is there any better way to be able to inject the UIDbContext into the DbFileProvider constructor Or any way to instantiate a UIDbContext inside DbFileProvider without IServiceProvider?
You don't want to use DbContext as a file provider source the way you did.
DbContext isn't thread-safe, so it won't work when you have one single DbContext instance for the whole provider, because multiple requests could call the DbContext and it's operation more than once at the same time, resulting in exception when trying to execute 2 queries in parallel.
You'd have to instantiate a connection (like in the linked article) or DbContext per IFileInfo/IDirectoryContents instance.
DbContextOptions<UIDbContext> should be registered as singleton, so you can resolve it onceinside Configure` w/o any issues and pass it to your provider.
Alternatively you can also call DbContextOptionsBuilder and build/construct a DbContextOptions<T>, but then you have to repeat the configuration for you did inside AddDbContext (i.e. .UseSqlServer()).
However it can be useful, as it allows you to set different settings (i.e. changing the way how includes, errors etc. are logged).

.net core, n-layered app, should services layer have dependency on Microsoft.Extensions.Options.dll

Straightforward question is: are Microsoft.Extensions.Options.IOptions meant to be used only within the context of umbrella app (web app in this case) or in class libraries also?
Example:
In a n-layered, asp.net core app we have services layer that is dependant on some settings coming from appsettings.json file.
What we first started with is something along these lines in Startup.cs:
services.Configure<Services.Options.XOptions>(options =>
{
options.OptionProperty1 = Configuration["OptionXSection:OptionXProperty"];
});
And then in service constructor:
ServiceConstructor(IOptions<XOptions> xOptions){}
But that assumes that in our Service layer we have dependecy on Microsoft.Extensions.Options.
We're not sure if this is recomended way or is there some better practice?
It just feels a bit awkward our services class library should be aware of DI container implementation.
You can register POCO settings for injection too, but you lose some functionalities related to when the appsettings.json gets edited.
services.AddTransient<XOptions>(
provider => provider.GetRequiredService<IOptionsSnapshot<XOptions>>().Value);
Now when you inject XOptions in constructor, you will get the class. But when your edit your appsettings.json, the value won't be updated until the next time it's resolved which for scoped services would be on next request and singleton services never.
On other side injecting IOptionsSnapshot<T> .Value will always get you the current settings, even when appsettings.json is reloaded (assuming you registered it with .AddJsonFile("appsettings.json", reloadOnSave: true)).
The obvious reason to keep the functionality w/o pulling Microsoft.Extensions.Options package into your service/domain layer will be create your own interface and implementation.
// in your shared service/domain assembly
public interface ISettingsSnapshot<T> where T : class
{
T Value { get; }
}
and implement it on the application side (outside of your services/domain assemblies), i.e. MyProject.Web (where ASP.NET Core and the composition root is)
public class OptionsSnapshotWrapper<T> : ISettingsSnapshot<T>
{
private readonly IOptionsSnapshot<T> snapshot;
public OptionsSnapshotWrapper(IOptionsSnapshot<T> snapshot)
{
this.snapshot = snapshot ?? throw new ArgumentNullException(nameof(snapshot));
}
public T Value => snapshot.Value;
}
and register it as
services.AddSingleton(typeof(ISettingsSnapshot<>), typeof(OptionsSnapshotWrapper<T>));
Now you have removed your dependency on IOptions<T> and IOptionsSnapshot<T> from your services but retain all up advantages of it like updating options when appsettings.json is edited. When you change DI, just replace OptionsSnapshotWrapper<T> with your new implementation.

Registering an Interceptor For All Interface Implementations in Castle Windsor

I'm fairly new to Castle Windsor and in particular using Interceptors and am wondering if it is possible to register an Interceptor across all implementations of a particular interface without specifying each implementation in turn. For example, I have an interface called IComponent which will be implemented by a number of classes. I have a ComponentInterceptor class written to act on these classes when they have executed a particular method. I would like to do something like:
_container.Register(
Component.For<IComponent>()
.Interceptors("ComponentInterceptor")
.LifestyleSingleton())
Rather than having to do:
_container.Register(
Component.For<IComponent>()
.ImplementedBy<ComponentA>()
.Interceptors("ComponentInterceptor")
.LifestyleSingleton()),
_container.Register(
Component.For<IComponent>()
.ImplementedBy<ComponentB>()
.Interceptors("ComponentInterceptor")
.LifestyleSingleton())
I found another approach, I wanted to register this interceptor for all components being registered and do this hopefully minimal fuss. To do this I follow this article and created a new class like this:
public class MyContributeComponentConstruct : IContributeComponentModelConstruction
{
public void ProcessModel(IKernel kernel, ComponentModel model)
{
if (model.Services.Any(s => s == typeof(IComponent)))
{
model.Interceptors.Add(InterceptorReference.ForType<ComponentInterceptor>());
}
}
}
and then add this contribute with the Castle Windsor container
container.Kernel.ComponentModelBuilder.AddContributor(new MyContributeComponentConstruct ());
You can register components in the container using conventions via the Classes class. The following registers all classes in the current assembly that implement IComponent under the service IComponent and with your ComponentInterceptor interceptor:
container.Register(
Classes.FromThisAssembly()
.BasedOn<IComponent>()
.WithService.FromInterface()
.Configure(c => c.Interceptors<ComponentInterceptor>())
);
The Windsor documentation provides a bunch of other examples and explains in detail what different classes are for.

Managing RavenDb session in Windsor under NServiceBus

I'm using NServiceBus (3.2.2), RavenDB (1.2.2017-Unstable) and Windsor (3.0.0.4001) in an MVC 4 project.
I have a IHandleMessages class that handles 3 different messages, and that needs an IDocumentSession, and therefore defines a property such as:
public IDocumentSession DocumentSession { get; set; }
I've copied the RavenDbUnitOfWork implementation from NServiceBus' website
I've registered IDocumentStore, IDocumentSession and IManageUnitsOfWork in my Windsor container as follow:
container.Register(
Component
.For<IManageUnitsOfWork>()
.ImplementedBy<RavenUnitOfWork>()
.LifestyleTransient()
);
container.Register(
Component
.For<IDocumentStore>()
.UsingFactoryMethod(k => DocumentStoreHolder.DocumentStore)
.LifestyleSingleton(),
Component
.For<IDocumentSession>()
.UsingFactoryMethod(k => k.Resolve<IDocumentStore>().OpenSession())
.LifestyleTransient()
);
NServiceBus is configured to use my container:
Configure.With()
.CastleWindsorBuilder(container);
I'm encountering the problem that the UnitOfWork and the message handler receive different instances of the DocumentSession. This means that objects stored in the session in the message handler are not saved, since SaveChanges() is called on a different DocumentSession.
Removing the Transient lifestyle causes different kind of problems, that result in concurrency/conflicts when updating objects from RavenDb, since (probably) the message handler keeps getting the same instance of the DocumentSession, which holds a cached version of the updated object.
Update:
As suggested, I've tried changing the registration of the IDocumentSession in Windsor, to the Scope lifestyle, like this:
Component
.For<IDocumentSession>()
.UsingFactoryMethod(k => k.Resolve<IDocumentStore>().OpenSession())
.LifestyleScope()
This causes exceptions when the container tries to resolve the MVC Controller, saying that the scope was not found, and asking if I forgot to call BeginScope().
You need to have a scope of Per Message, not transient or singleton.
I am assuming that your mvc controller has a direct dependency on the IDocumentStore. You need to call container.BeginScope() before each request from the web. You can either do this as an action filter attribute http://msdn.microsoft.com/en-us/library/system.web.mvc.actionfilterattribute.aspx or as an AOP aspect on the controller itself http://cangencer.wordpress.com/2011/06/02/asp-net-mvc-3-aspect-oriented-programming-with-castle-interceptors/.
The issue is you need different lifestyles when using nservicebus in an asp.net mvc website when sharing the IDocumentSession in the same container.
For ASP.NET MVC you need a PerWebRequest lifestyle and for NServiceBus you need the Scoped lifestyle.
To do that i've used the hybrid lifestyle code in the castle contrib project:
https://github.com/castleprojectcontrib/Castle.Windsor.Lifestyles/tree/master/Castle.Windsor.Lifestyles
When calling from an ASP.NET context, it uses the WebRequestScopeAccessor. For NServicebus you need the LifetimeScopeAccessor. This is not in the contrib project, but is easy to add:
public class HybridPerWebRequestLifetimeScopeScopeAccessor : HybridPerWebRequestScopeAccessor
{
public HybridPerWebRequestLifetimeScopeScopeAccessor()
: base(new LifetimeScopeAccessor())
{
}
}
And in your registration code you need something like:
container.Register(Component.For<IDocumentSession>().LifestyleScoped<HybridPerWebRequestLifetimeScopeScopeAccessor>().UsingFactoryMethod(() => RavenDbManager.DocumentStore.OpenSession()));
And here's an implementation for Rhino Service Bus i used before switching to nservicebus:
https://gist.github.com/4655544

Castle Windsor inject types dynamically based on attributes or config file

I have an idea to design something like this. My class can accept a sequence of exception handlers that are registered when an instance of the class is created.
class Foo {
public Foo (IEnumerable<UnhandledExceptionEventHandler> handlers) {
foreach(var handler in handlers) {
AppDomain.CurrentDomain.UnhandledException += handler;
}
}
}
Now, I'd like to do something like this. I want to have Castle Windsor inject the handlers for me either based on attributes applied to the class
[LogExceptions(typeof(SomeExceptionHandler), typeof(AnotherExceptionHandler))]
class Foo { // code }
or specified in a config file. So in the former example, when Castle Windsor wants to resolve an instance of Foo, it would look at the LogExceptions attribute and see that it needs to construct Foo via
new Foo(new[] { new SomeExceptionHandler(), new AnotherExceptionHandler() });
What are the concepts in Castle Windsor that I want to look at that will enable me to solve this problem?
If my design is retarded, please say so but offer constructive ideas! Thanks!
The best extension point for stuff like that is ComponentModel construction contributors. You will need to discover what handlers apply to your component, and then construct an array of service override dependencies for them.