Windsor installer configuration - castle-windsor

I have an application built with Windsor, this application has features and al the components are manually registered inside xml which also contains their configuration. This is an example:
<component type="type">
<parameters>
[...]
</parameters>
</component>
I decided to refactor my components and separate them into windsor installers, one installer for each feature. My problem now is to decide where to put the configuration of the components registered inside each installer.
Before this decision, the user could find the appropriate configuration of the components mostly inside the parameters element of xml, and I did not have to write wire logic for that to work.
Now I'm a bit confused because it seems like I don't have anymore such automatism. Since I decided to declare the installers of my application by xml, I think it could be perfect if I could put this configuration inside the installr element like this:
<installers>
<install assembly="myassembly">
<parameters>
[...]
<parameters>
</install>
</installers>
I don't know if Windsor supports this syntax. If it does, then I wonder how I could access it from inside the installer and how to wire it up to my components and services.
Another accettable alternative could be to create and register on xml a component containing all the configuration of my feature:
<components>
<component type="featureConfiguration">
<parameters>
</parameters>
</component>
</components>
In this case I guess that I have to refactor my components to let them receive such type as argument in their constructor whereas before I had direct properties, in other words before I could tell exactly what were the dependencies of my components by looking at the code, with this new form I pass to them the whole configuration but I don't know anymore what specific properties of the configuration are used in this or that component.
To use this second solution and to avoid this confusion I should avoid to pass the whole configuration to my subcomponents, and let that single properties do the work, but I have to find a glue between the properties of this configuration component and the properties of the components and services of the installer.
I think that rather than a component I could also put all my configuration inside the properties element of xml:
<properties>
<featureConfiguration>
[property list]
</featureConfiguration>
</properties>
but again, I have to find the glue between each single property in the list and the properties of my components.
Any help is appreciated.
Thank you.

Maybe you will find this mixed solution helpful, depending on the level of the parameterization of your components that you need. Namely, you could perform the component registration in your installers and set the parameters of the components in a windsor config file. This is useful when you have parameterization needs on few of your components while letting Windsor handle all other dependencies.
Example:
Let's say that you have the following components.
public class MyComponent
{
public MyComponent(MyDependency dependency, string stringParameter, DateTime dateParameter)
{
this.Dependency = dependency;
this.StringParameter = stringParameter;
this.DateParameter = dateParameter;
}
public DateTime DateParameter { get; set; }
public string StringParameter { get; set; }
public MyDependency Dependency { get; set; }
}
public class MyDependency
{
}
Then you could use the following installer to register them.
public class MyInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Component.For<MyComponent>().Named("MyComponent"));
container.Register(Component.For<MyDependency>());
}
}
Note, that we have been explicit about the unique name of the component, set to MyComponent. But you can use also the default full name.
The windsor config file could look like this:
<configuration>
<components>
<component id="MyComponent">
<parameters>
<stringParameter>Some string</stringParameter>
<dateParameter>2013/09/25</dateParameter>
</parameters>
</component>
</components>
</configuration>
And now you can wrap it all together:
WindsorContainer container = new WindsorContainer();
container.Install(Configuration.FromXmlFile("windsor.config"));
container.Install(FromAssembly.This());
Note that the order of invoking the Install method is important; you must first install the config file settings.

Related

JSONProvider namespaceMap config in web.xml for Apache CXF

I need to pass a namespaceMap to the JSONProvider configuration via web.xml file in Apache CXF.
I do not use Spring on this application and do not do programmatic configuration of Providers like this question suggests: CXF: No message body writer found for class - automatically mapping non-simple resources
Rather use configuration in the style of this non-Spring example from the CXF code.
But, the example does not show how to provide a namespaceMap and I'm unsure of how to specify a map in that style of configuration.
I'm going ahead with some trial-and-error.
Anyone know of a reference guide for the syntax for the JSONProvider config via web.xml?
I was not able to find a reference guide, but did manage to solve the configuration issue by some code spelunking and this mailing list thread from the archives.
For some reason, the suggestion from that mailing list thread didn't work (it was ignoring the custom JSONProvider from the web.xml). I may have had other problems.
Ultimately, I moved away from the idea of web.xml configuration since it was already used to provide a javax.ws.rs.Application and (from looking # CXF code), it appears that CXF ignore init-param elements from web.xml if it finds an Application.
Further, there doesn't seem be a way of expressing Map types in the web.xml config. That's conjecture based on the thread and looking at the code, so I can't 100% confirm.
This is what my web.xml looks like (same before and after these changes):
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>my.javax-ws-rs.Application</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
It was in the my.javax-ws-rs.Application class that I needed to make changes.
Simply added a new JSONProvider to the list of singletons in there:
#Override
public Set< Object> getSingletons() {
final Set< Object> singletons = new HashSet<>();
// [SNIP -- existing singletons]
singletons.add( new my.provider.MyJSONProvider() );
return singletons;
}
The definition of my.provider.MyJSONProvider is where the rest of the magic happens (yes, it's the "programmatic" configuration that I said I didn't have, but ultimately had to resort to):
#Produces({MediaType.APPLICATION_JSON})
#Consumes({MediaType.APPLICATION_JSON})
#Provider
public class MyJSONProvider<T> extends JSONProvider<T> {
public AdministrationUtilisatuerJSONProvider() {
{
Map<String, String> newNamespaceMap = new ConcurrentHashMap<>();
XmlSchema resource1SchemaAnnotation = Resource1.class.getPackage().getAnnotation(javax.xml.bind.annotation.XmlSchema.class);
String resource1Namespace = resource1SchemaAnnotation.namespace();
newNamespaceMap.put( resource1Namespace, "resource1JsonPrefix" );
XmlSchema resource2SchemaAnnotation = Resource2.class.getPackage().getAnnotation(javax.xml.bind.annotation.XmlSchema.class);
String resource2Namespace = resource2SchemaAnnotation.namespace();
newNamespaceMap.put( resource2Namespace, "resource2JsonPrefix" );
setNamespaceMap(newNamespaceMap);
}
// Or set this to "true" to ignore all that namespace stuff
// setIgnoreNamespaces(true);
// Don't write namespace for default xsi-type elements.
setWriteXsiType(false);
// [SNIP] -- Other JSONProvider configuration.
// Check source from CXF, but few comments in code.
}
One final note about getting Jettison-based JSON working in CXF: you also need the cxf-rt-rs-extension-providers-X.Y.Z.jar on your classpath. This isn't documented in the CXF WHICH_JARS file, but is required.

How to pass configuration parameters to SimpleInjector packaging?

So SimpleInjector now has a packaging nuget that you can use to isolate different aspects of root composition.
Say I have a configurable composition root in a library that is reused by multiple projects in an application. For example, in an Azure solution I might have a Web role and a Worker role which share a large set of the same dependencies for the most part, but with slightly different configuration options depending on the consumer. When I compose the root, I can pass in a plain old RootCompositionSettings object with properties that tell SimpleInjector how to register dependencies.
However, I am not sure how (or if) I can pass these settings to an IPackage instance. Is it possible to pass custom settings to a SimpleInjector package, and if so, how?
I see that the standard practices for registering packages is to invoke either
container.RegisterPackages(); // scans all loaded assemblies for IPackage
// or
container.RegisterPackages(IEnumerable<Assembly>) // specific assemblies only
...so how can we pass parameters into the packaging instance(s)? Is there some way to do it via the container?
The trick here is to pass the information on with the container to the package. You can do this by using the container's Items dictionary, that is much like ASP.NET's HttpContext.Items collection. This can be done as follows:
using SimpleInjector.Advanced;
container.SetItem(typeof(RootCompositionSettings), settings);
container.RegisterPackages();
Now inside your packages, you can do the following:
var settings =
(RootCompositionSettings)container.GetItem(typeof(RootCompositionSettings));
Please note that:
SetItem and GetItem are extension methods that are located in the SimpleInjector.Advanced namespace. Those methods allow you to access the (internal) Items dictionary.
You can pass in any key you like. Passing in typeof(RootCompositionSettings) is just convenient in this case, but not required.
If you need to call the settings in more places, it might be useful to create a more specific extension method that allows you to access the setting instance, but that's up to you.
Another option is to not use the IPackage interface and the SimpleInjector.Packaging library at all. In most cases it doesn't really add anything and you could simply define a public static method in the assembly that does the same as a package does. For instance:
public static class BusinessLayerBootstrapper
{
public static void Bootstrap(Container container, ScopedLifestyle scopedLifestyle,
RootCompositionSettings settings)
{
// Here the same logic as what you would write in your package.
}
}
Most applications are not that dynamic that you need to load assemblies dynamically and the startup project usually has a hard reference to all the other assemblies. In that case it is perfectly sane to simply call a static method.
And even if you have the requirement of dynamically loading assemblies and allowing them to register their stuff in the container, it's quite trivial to build your own IPackage abstraction instead:\
// Your own IPackage interface
public interface IPackage
{
void RegisterServices(Container container, RootCompositionSettings settings);
}
// Your own extension method
public static void RegisterPackages(this Container container,
RootCompositionSettings settings)
{
var packages =
from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetExportedTypes()
where typeof(IPackage).IsAssignableFrom(type)
where !type.IsAbstract
select (IPackage)Activator.CreateInstance(type);
packages.ToList().ForEach(p => p.RegisterServices(container, settings));
}
In fact, except for some extra validations and filtering out dynamic assemblies, the SimpleInjector.Packaging project is not much more than this.

ReSharper Custom Conversion - AutoProperty to MvxProperty

in our architecture, we have a bunch of models like this
public class UserModel
{
public string FirstName {get;set;}
}
and since we're using MvvmCross for our view models, we need our properties to look like this
public class UserViewModel: MvxViewModel
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set { _firstName = value; RaisePropertyChanged(() => FirstName); }
}
}
Now I've already got an R# template to write my own mvx properties by simply typing propmvx, but I still need to type in the type and the name.
I'm wondering if there's a way to setup a custom conversion template in order to have the alt + enter context menu to have a second option... something like
[T]o property with backing field
To [M]vx property with backing field
This is possible, even without creating any custom plugins or patterns, by using ReSharper Annotations. I have recently recorded a webinar with JetBrains, demonstrating exactly how to solve this with annotations. You can watch it here.
Short answer: the method
public void RaisePropertyChanged<T>(Expression<Func<T>> property)
of MvxNotifyPropertyChange.cs needs to be annotated with the NotifyPropertyChangedInvocatorAttribute, and then you could simply Alt-Enter on the property, and change it to a Property with change notificaton.
Now, since you can't (or don't want to) modify the source code of MvvmCross, you could apply those annotations externally, via XML. Take a look at the ExternalAnnotations directory, located in your ReSharper installation directory. It contains a bunch of external annotations for other MVVM frameworks. It's a simple XMLDoc format, so you could create an XML for MvvmCross and write the appropriate methods there. After that, save the file under a directory MvvmCross (or however the assembly is called), reload your solution, and it should just work!
For more information, please watch my webinar (link above), or JetBrains help
Here's an External Annotations file that will work with that method.
Cirrious.MvvmCross.ExternalAnnotations.xml
<?xml version="1.0" encoding="utf-8"?>
<assembly name="Cirrious.MvvmCross">
<member name="M:Cirrious.MvvmCross.ViewModels.MvxNotifyPropertyChanged.RaisePropertyChanged``1(System.Linq.Expressions.Expression{System.Func{``0}})">
<attribute ctor="M:JetBrains.Annotations.NotifyPropertyChangedInvocatorAttribute.#ctor" />
</member>
</assembly>
And here it is in action:

Help with Castle Windsor XML configuration

I have the following three components defined in the Caste-Windsor XML configuration for my application:
<component id="StringFactory"
service="IStringFactory, MyApp"
type="DefaultStringFactory, MyApp"
lifestyle="singleton"
/>
<component id="TheString"
type="System.String"
factoryId="StringFactory"
factoryCreate="CreateString"
>
<parameters>
<name>SomeString</name>
</parameters>
</component>
<component id="TheTarget"
service="ITarget, MyApp"
type="TheTarget, MyApp"
lifestyle="transient"
>
<parameters>
<aString>${TheString}</aString>
</parameters>
</component>
And the following facility defined:
<facility id="factory.support"
type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel"
/>
When I run the application and set a breakpoint in the constructor of the TheObject class, the value passed in as the aString parameter is "${TheString}" when I expect it to resolve to the value of the component with that name.
Also, I have a breakpoint in the StringFactory constructor and CreateString method, neither of which are hit. I know the configuration is being used as other components are resolving correctly.
What am I missing or doing wrong here?
UPDATE
In light of the huge tangient this topic has taken, I've refactored the code above to remove anything to do with connection strings. The original intent of this post was about injecting a property with the value returned from a method on another object. Somehow that point was lost in a discussion about why I'm using XML versus code-based configuration and if this is a good way to inject a connection string.
The above approach is far from an original idea and it was pulled from several other discussions on this topic and our requirements are what they are. I'd like help understanding why the configuration as it is in place (whether the right approach or not) isn't working as expected.
I did verify that the first two components are being instantiated correctly. When I call Container.Resolve("TheString"), I get the correct value back. For whatever reason, The parameter syntax is not working correctly.
Any ideas?
While not a definitive solution to what I need to do in my application, I believe I've figured out what is wrong with the code. Or at least I've found a way to make it work which hints at the original problem.
I replaced the String type for TheString with a custom class. That's it. Once I did that, everything worked fine.
My guess is that it has something to do with the fact that I was trying to use a ValueType (primitive) as a component. I guess Castle doesn't support it.
So, knowing that's the case, I can now move on to figuring out if this approach is really going to work or if we need to change direction.
UPDATE
For the sake of completeness, I thought I'd go ahead and explain what I did to solve my problem AND satisfy my requirements.
As before, I have access to my configuration settings through an IConfigurationService defined as:
<component id="ConfigurationService"
service="MyApp.IConfigurationService, MyApp"
type="MyApp.RuntimeConfigurationService, MyApp"
lifestyle="singleton"
/>
This is automatically injected into my (new) IConnectionFactory which is responsible for generating IDbConnection objects based on the connection strings defined in the application's configuration file. The factory is declared as:
<component id="ConnectionFactory"
service="MyApp.Factories.IConnectionFactory, MyApp"
type="MyApp.Factories.DefaultConnectionFactory, MyApp"
lifestyle="singleton"
/>
In order to resolve what connection is used by my repository, I declare each connection as a component using the ConnectionFactory to create each instance:
<component id="MyDbConnection"
type="System.Data.IDbConnection,
System.Data, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089"
factoryId="ConnectionFactory"
factoryCreate="CreateConnection"
lifestyle="transient"
>
<parameters>
<connectionStringName>MyDB</connectionStringName>
</parameters>
</component>
Notice the fully described reference to System.Data. I found this is necessary whenever referencing assemblies in the GAC.
Finally, my repository is defined as:
<component id="MyRepository"
service="MyApp.Repositories.IMyRepository, MyApp"
type="MyApp.Sql.SqlMyRepository, MyApp.Sql"
lifestyle="transient"
>
<parameters>
<connection>${MyDbConnection}</connection>
</parameters>
</component>
Now everything resolves correctly and I don't have ANY hard-coded strings compiled into my code. No connection string names, app setting keys or whatever. The app is completely reconfigurable from the XML files which is a requirement I must satisfy. Plus, other devs that will be working with the solution can manage the actual connection strings in the way they are used to. Win-win.
Hope this helps anyone else that runs into a similar scenario.
You don't really need XML registrations here, since you probably don't need to swap components or change the method used without recompiling. Writing a configurable app does not imply having to use XML registrations.
The problem with this particular XML registration you posted is that the connection string is a parameter, but it's treated like a service.
Doing this with code registrations is much easier, e.g.:
var container = new WindsorContainer();
container.Register(Component.For<IConfigurationService>().ImplementedBy<RuntimeConfigurationService>());
container.Register(Component.For<ITheRepository>().ImplementedBy<TheRepository>()
.LifeStyle.Transient
.DynamicParameters((k, d) => {
var cfg = k.Resolve<IConfigurationService>();
d["connectionString"] = cfg.GetConnectionString();
k.ReleaseComponent(cfg);
}));
Or if you don't want to depend on IConfigurationService, you could do something like:
container.Register(Component.For<ITheRepository>().ImplementedBy<TheRepository>()
.LifeStyle.Transient
.DependsOn(Property.ForKey("connectionString")
.Is(ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["connName"]].ConnectionString))

Unity IOC Configuration

I have a class
public class Broker
{
public Broker(string[] hosts, string endPoint, string port, Type remoteType)
{
}
}
Which I want to configure using Unity XML Configuration, I can configure it using code in C# as follows already, where "container" is my Unity container
container.Configure<InjectedMembers>()
.ConfigureInjectionFor<Broker>("myBroker",
new InjectionConstructor(hosts, endPoint, port, new InjectionParameter(typeof(IMyBrokeredObject))));
and it will happly resolve using the normal unity calls
container.Resolve("myBroker");
But currently my xml cannot resolve the final parameter IMyBrokeredObject, I get a resolution exception, as Unity is trying to resolve the type insted of simply injecting the type, as it does in the code above.
Any Ideas?
Have you defined the type in the configuration file:
<unity>
<typeAliases>
<typeAlias alias="IMyBrokeredObject" type="MyAssembly.IMyBrokeredObject, MyAssembly" />
</typeAliases>
<containers>
<container>
<types>
<!-- Views -->
<type type="IMyBrokeredObject" mapTo="MyAssembly.MyBrokeredObjectImplementation, MyAssembly" />
But my problem is that there is no implementation available for the IMyBrokeredObject, what is actually happening in the background of this is that the broker provides remote objects given an interface, the actual implementation is somewhere else.
In code I can get the container to provide an broker by giving an "InjectionParameter", I cannot find out how to do this in the xml configuration.
its tricky because I dont want the container to give an instance of the interface but to actually pass the interface as is, the "InjectionParameter" is a store for a value, the stored value is handed in when the object is created by the container, as is. What I am looking for is the required configuration xml to create the InjectionParameter and give it the value, if that is at all possible?