I have an object that contains a property:
public Dictionary<string, Dictionary<string, List<ContextMenuItemModel>>> ContextMenuModel { get; set; }
How do I use Spring.Net to configure this property?
Well, configuring this in xml isn't pretty, consider switching to Spring.Net code config to configure your spring context in C#.
Anyway, to do this in xml, you use the constructors of the generic .net collections. For instance, List<T> takes an IList<T> constructor, so you can configure a list of strings as follows:
<object id="list1" type="System.Collections.Generic.List<string>">
<constructor-arg>
<list element-type="string">
<value>abc</value>
<value>def</value>
</list>
</constructor-arg>
</object>
Note that in xml you have to use <, because using < isn't legal xml. Setting generic collection values is discussed in the Spring.net docs.
A generic Dictionary<string, System.Collections.Generic.List<string>> can be configured in a similar manner, which is also discussed in this answer:
<object id="dic1" type="System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<string>>">
<constructor-arg>
<dictionary key-type="string" value-type="System.Collections.Generic.List<string>">
<entry key="keyToList1" value-ref="list1" />
<entry key="keyToList2" value-ref="list2" />
</dictionary>
</constructor-arg>
</object>
And you probably see the next one coming now:
<object id="dic0" type="System.Collections.Generic.Dictionary<string, System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<string>>>">
<constructor-arg>
<dictionary key-type="string" value-type="System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<string>>">
<entry key="keyToDic1 " value-ref="dic1" />
</dictionary>
</constructor-arg>
</object>
Which can be injected:
<object id="MyObject" type="MyNamespace.MyClass, MyAssembly">
<property name="ContextMenuModel" ref="dic0" />
</object>
This isn't really pretty, but you can slightly improve the readability of your xml using type aliases.
Related
In my dependency injection configuration file - I don't know (and can't find an example) on how to set into a member some predefined environment variable file.
Can't tell how to do it in Spring.Net - your help will be appreciated.
Use an EnvironmentVariableSource, the current docs are somewhat lacking at the moment: http://springframework.net/docs/1.3.2/reference/html/objects.html#objects-variablesource. I've written some additional docs, they'll probably be included in the next 2.0 release of the build. In the meantime you can also check this example code on Github https://github.com/serra/spring-net-examples/tree/master/Spring.IoCQuickStart.VariableSources.
Take a look to the VariablePlaceholderConfigurer object. It should do the job:
http://www.springframework.net/doc-latest/reference/html/objects.html#objects-variablesource
<object type="Spring.Objects.Factory.Config.VariablePlaceholderConfigurer, Spring.Core">
<property name="VariableSources">
<list>
<object type="Spring.Objects.Factory.Config.EnvironmentVariableSource, Spring.Core"/>
</list>
</property>
</object>
<object type="MyObject">
<property name="MyProperty" value="${MyEnvironmentVariableName}"/>
</object>
The project structure is:
Now I am trying to create a bean NHibernateSessionFactory as:
<object id="NHibernateSessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate32">
<property name="DbProvider" ref="DbProvider"/>
<property name="MappingResources">
<list>
<value>EMSApplication.Domain/EMSApplication.hbm.xml</value>
</list>
</property>
<property name="HibernateProperties">
<dictionary>
<entry key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
<entry key="dialect" value="NHibernate.Dialect.MsSql2008Dialect"/>
<entry key="connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>
<entry key="proxyfactory.factory_class" value="NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate"/>
<entry key="show_sql" value="true"/>
<entry key="hbm2ddl.auto" value="update"/>
<entry key="cache.use_query_cache" value="true"/>
</dictionary>
</property>
<property name="ExposeTransactionAwareSessionFactory" value="true" />
</object>
But I am getting the error message:
Error creating context 'spring.root': file [C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\10.0\EMSApplication.Domain\EMSApplication.hbm.xml] cannot be resolved to local file path - resource does not use 'file:' protocol.
Now the project is on D drive, I am wondering why this is pointing C drive?
Also how can I add the specified hbm file in the mapping resource? This file is set as 'Embedded Resource'.
Is there any way to specify a directory here to scan for the multiple hbm files?
Any information will be very helpful to me.
You are not using a protocol identifier (e.g. file:// or assembly://) in your resource name, so Spring uses the default file protocol. It tries to resolve the hbm file from the location where the web app is running (the devserver path), not where it's files are stored, which you seem to expect.
To reference a file in your website use a ~ to identify the root of your web site, e.g. <value>file://~/EMSApplication.Domain/EMSApplication.hbm.xml</value>. But make sure the file is copied, which might not be the case, since you have set it to embedded resource (why?).
Consider the following improvements, they'll make your live more easy:
move the code in your folders dao, domain and NHibernate to a separate assembly (a class library project that is referenced from your web application) named Your.AssemblyName.
The session factory also supports specifying mapping assemblies to scan, so that you don't have to specify each file - see the docs on setting up a session factory using spring.net. Specify Your.AssemblyName in the mapping assembly list:
<object id="MySessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate">
<property name="DbProvider" ref="DbProvider"/>
<property name="MappingAssemblies">
<list>
<value>Your.AssemblyName</value>
</list>
</property>
<property name="HibernateProperties">
<!-- snip -->
</object>
And check out the NHibernate example in the spring docs - it's very applicable to the questions you are raising here.
Is there way in Spring for .NET how to use translated message from an IMessageSource as constructor argument for other object in the xml application context file? Something like <spring:message> in Java. My example:
<!-- my message source -->
<object name="messageSource" type="MyMessageSource"></object>
<object type="MyLocalizedObject">
<!-- my object, where I need to pass tranlated message into the argument: -->
<constructor-arg name="localizedTitle" value=">{translated title.key}<"/>
</object>
Well, you could do it with an expression:
<object name="messageSource" type="MyMessageSource"></object>
<object type="q9257449_springmessage.MyClass, q9257449_springmessage">
<constructor-arg name="localizedTitle"
expression="#(messageSource).GetMessage('HelloMessage', 'mr.', 'Anderson')" />
</object>
There might be a better way to achieve this, but in the meantime this should get you going.
In C#.NET4.0 with Windsor castle IoC Framework v2.5.3,
is it possible to configure embbeded Dictionaries ?
I tried some configuration (see below) without success.
Here the Components.xml file
<component
id="MyComponent"
service="MyAssembly.IMyInterface,MyAssembly"
type="MyAssembly.MyClass,MyAssembly">
<parameters>
<MyProperty>#{MyComplexDictionaryProperty}</MyProperty>
</parameters>
</component>
Here the ComponentsProperties.xml file:
<MyComplexDictionaryProperty>
<Dictionary
keyType="MyAssembly.MyEnum1,MyAssembly"
valueType="... ??? ...">
<Entry key="MyEnum1Value1">
<Dictionary
keyType="MyAssembly.MyEnum2,MyAssembly"
valueType="System.Int32, mscorlib">
<Entry key="MyEnum2Value1">1</Entry>
</Dictionary>
</Entry>
</Dictionary>
</MyComplexDictionaryProperty>
Thanks :-)
I've never seen that done before. According to the documentation on XML configuration, the hash mark (#) syntax is used for referencing another property in the config file in the format "property.id". Are you sure you're using it correctly?
I'm using Spring.NET's IoC container and everything has been working just fine....until now. Somehow, in one of our previous releases, we introduced a circular dependency. Since we use setter based injection as opposed to constructor based injection, Spring.NET just kept humming along fine, but the behavior of our app changed.
Now I have a solution with a hundred or so components, and somewhere in that pile of components exists a circular dependency, which I now need to find.
Are there any tools that can take my Spring.NET config files and give me a graphical picture of my components and their dependencies?
AFAIK there isn't such a tool available, although there is one for spring for Java.
This thread on the spring.net forum
discusses the issue and proposes a solution.
I made a quick-and-dirty proof of concept based on Thomas Darimont's approach using QuickGraph.
For the following configuration file:
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">
<object id="a1" type="q7446068.ClassA, q7446068" >
<property name="MyOtherA" ref="a2" />
</object>
<object id="a2" type="q7446068.ClassA, q7446068" >
<property name="MyOtherA" ref="a1" />
</object>
<object id="a3" type="q7446068.ClassA, q7446068" />
</objects>
I was able to create the following dot file:
digraph G {
0 [label="a1"];
1 [label="a2"];
2 [label="a3"];
0 -> 1 [];
1 -> 0 [];
}
Which shows the circular dependency.
The code is available as a gist.