I have an configuration error with Unity.
I am trying to implement http://unitymvc3.codeplex.com/, but i am stucked right now, because of this:
In my unity configuration I have this settings:
<register type="IMainDbContext" mapTo="WorkflowContext">
<lifetime type="hierarchical" />
<constructor></constructor>
</register>
But at the time of creating unity, (my simple code is here:)
UnityConfigurationSection section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
if (section != null)
{
section.Configure(container);
}
this.container = container;
everything is configured great, except of registration "IManDbContext" which has LifetimeManagerType = {Name = "TransientLifetimeManager" FullName = "Microsoft.Practices.Unity.TransientLifetimeManager"}, but it should be hierarchical lifetime manager
Have you got any ideas how tell unity (in configuration, not in code) i want hierarchical lifetime manager?
Thanks for any tips.
My error was caused by this error:
I have multiple DbContext, but they was badly configured:
<register type="IMainDbContext" mapTo="WorkflowContext">
<lifetime type="hierarchical" />
<constructor></constructor>
</register>
<register type="IReportDbContext" mapTo="SomeBadContext">
<lifetime type="hierarchical" />
<constructor></constructor>
</register>
When I was using this configuration, which was bad, unity simple don`t configure any lifetime manager. After I set these context right, unity used my lifetime manager configurations just right.
I don't think you can. If you're specifying the lifetime type you need to either supply "singleton" or "external" (external being a custom lifetime).
Link to Unity Schema Documentation
In fairness, unless you're using multiple Unity containers I don't see the value of having a hierarchical lifetime manager, as this is designed to ensure that you only have one instance of your type instantiated in the main unity container and any child containers you generate from it.
So, unless you're planning on generating child containers and want a separate instance of your IMainDbContext inplmenting object, you might as well just using "singleton" lifetime manager.
Related
I've been running into endless problems attempting to use Windsor with Web API and injecting HttpRequestMessage into downstream dependencies of a controller. Since I've tried all the matching answers on Stackoverflow, I'd like to ask the question in a different way:
In Castle Windsor, how can I resolve a component instance while supplying a value for a downstream dependency? That is, the supplied value is required by a component that is required by the component being resolved.
For context, I'm trying to inject HttpRequestMessage so that I can use it to resolve the request context (primarily to resolve an absolute URL).
Edit I'd also like to point out that I don't currently have a dependency on Web Host / System.Web and I'd rather not change that.
A proper approach is to
Create IMyDesiredRouteParameterProvider
Implement it. Get the current request inside it and get the url
Register it and inject it in the desired dependent class via constructor.
I made myself such an implementation and I can say that this way it works fine. You can make Web.Infrastructure assembly and put the implementation there. Or put both the interface and the implementation there if you are going to reference it from another web module.
using System;
using System.Web;
namespace RouteParameterProvider
{
interface IMyRouteParameterProvider
{
string GetRouteParameter();
}
public class ControllerActionMethodRouteParameterProvider : IMyRouteParameterProvider
{
public string GetRouteParameter()
{
string Parameter = HttpContext.Current.Request.RequestContext.RouteData.Values["controller"] as string;
if (string.IsNullOrEmpty(Parameter))
{
throw new InvalidOperationException();
}
return Parameter;
}
}
}
You can get every possible thing that the Request Context contains from :
HttpContext.Current.Request.RequestContext
And it will be better if you rethink your design decision :
I need HttpRequestMessage to be regstered prior to creating each
instance of SomethingController so that it will be available down at
the LinkGenerator layer.
Containers are to be initialized at runtime and then used to resolve.
I need HttpRequestMessage to be regstered prior to creating each
instance of SomethingController so that it will be available down at
the LinkGenerator layer.
It sounds like you want to register an item with the container at runtime, post-startup. In general, this is not a good practice--registration should be a discrete event that happens when the app is fired up, and the container's state should not be changed during runtime.
Dependency Injection is about resolving service components, not runtime state--state is generally passed via methods (method injection). In this case it sounds like your LinkGenerator component needs access to the ambient state of the request.
I'm not that familiar with HttpRequestMessage, but this answer seems to show that it is possible to retreive it from HttpContext.Current. You could make this a method on your LinkGenerator class, or wrap this call in a separate component that gets injected into LinkGenerator (HttpRequestMessageProvider?). The latter would be my preferred method, as it allows LinkGenerator to be more testable.
Given the lack of a clean way of doing this and Web API not providing information as to the hosted endpoint beyond per-request context objects, I ended up injecting the base url from configuration.
Is this library by Mark Seemann the answer? In the description he writes explicitly :
This approach enables the use of Dependency Injection (DI) because the
request can be injected into the services which require it.
Then gives an example :
// Inside an ApiController
var uri = this.Url.GetLink(a=> a.GetById(1337));
By which you can then pass the URL down the road in the service that you have injected in the controller.
UPDATE :
Mark Seemann wrote about the same exact problem here:
"Because HttpRequestMessage provides the context you may need to
compose dependency graphs, the best extensibility point is the
extensibility point which provides an HttpRequestMessage every time a
graph should be composed. This extensibility point is the
IHttpControllerActivator interface:..."
This way you can pass request context information to a component deep in the object graph by getting from the HttpRequestMessage and passing it to the DI container.
Just take a look at the interface of IHttpControllerActivator.
The WEB API framework gets the IHttpControllerActivator through DependencyResolver. You probably already replaced it by your CastleWindsorDependencyResolver. Now you have to implement and register your HttpControllerActivator and register it.
When the WEB API framework gets IHttpControllerActivator from DependencyResolver (your Castle Windsor DR) and calls IHttpControllerActivator.Create() it will pass you the HttpRequestMessage. You can get your info from there and pass it to the your CastleDR before you call Resolve(typeof(MyController)) which will resolve the whole object graph - that means you will have MyHttpContextInfo to inject in your XYZComponent deep in the resolution stack.
This way tou are passing the arguments in the last possible moment but it is still possible. In Castle Windsor I make such passing of arguments though CreationContext.AdditionalArguments["myArgument"];.
I am developping J2EE application with appfuse that have default settings with mySQL
<!-- Database settings -->
<dbunit.dataTypeFactoryName>org.dbunit.ext.mysql.MySqlDataTypeFactory</dbunit.dataTypeFactoryName>
<dbunit.operation.type>CLEAN_INSERT</dbunit.operation.type>
<hibernate.dialect>org.hibernate.dialect.MySQL5InnoDBDialect</hibernate.dialect>
<jdbc.groupId>mysql</jdbc.groupId>
<jdbc.artifactId>mysql-connector-java</jdbc.artifactId>
<jdbc.version>5.1.27</jdbc.version>
<jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName>
<jdbc.url>jdbc:mysql://localhost/${db.name}?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf-8&autoReconnect=true</jdbc.url>
<jdbc.username>root</jdbc.username>
<jdbc.password></jdbc.password>
<jdbc.validationQuery>SELECT 1 + 1</jdbc.validationQuery>
But i need to connect my application with external database (SQL QERVER)to retreive some data.
I need help to configure maven to use two different database (mysql +sql server)
maven will help you out with loading of the driver jar files. You would be creating two data source / session factory to achieve this.
I think this can be achieved quite easily in a brief guideline as follows:
Create a second "dataSource" bean definition in applicationContext-resources.xml with MSSQL specific values such as driver class, url etc. Give it a different bean id, "dataSourceMSSQL" perhaps. Bind them up to different properties file if you don't want to hard coded property values. For simplicity you can just hard coded it (not recommended). If you chose otherwise, you need to create another properties file to store mssql connection properties, perhaps jdbc-mssql.properties and add it into propertyConfigurer list. This also require you to make changes to your pom file to include custom settings under <!-- Database settings --> section. This can be a bit complicated.
Create another "sessionFactory" bean definition in applicationContext-dao.xml with MSSQL specific values such as hibernate dialect etc. and binds it to "dataSourceMSSQL" as dataSource property ref. Give it a different bean id perhaps, "sessionFactoryMSSQL".
Wire your DAOs which require the new sessionFactory i.e.:
#Autowired private SessionFactory sessionFactoryMSSQL;
Hope that will work for you.
Can someone please help me understand several things?
Do I still have to register PerRequestModule to use
LifeStylePerWebRequest? I use Castle.Windsor 3.2.0.0 and it seems
everything works without this module. I definetly remember that
there was an exception before that tells me "You forget to register
this module".
What "objects tracked by release policy" really
means? I use several Components with LifeStyleTransient but when I
Resolve one I get it in "objects tracked by release policy"
property, when I Resolve others I don't get them there.
How can I check the actual objects stored inside the container (and their
number)?
1) I guess since version 3.x PerRequestModule will be automatically registered by windsor.
2) An object will be tracked by windsor only if needed(for ex if its lifestyle is Transient and it implements IDisposable interface).
3) You can run unit tests checking for handlers or manually set a debug point once you registered all components and navigate with VS viewer container object: it has a property that lists all registered components.
My problem is every time after changing the Liferay portal-properties (and this is frequent especially at beginning of a new portal project) I need to restart the whole portal.
Some properties I can set over hook and these values will be changed after redeployment. Also that must be possible to change most portal properties at run time.
However, do you know some approach to reflect changes in portal-ext.properties without restarting Liferay portal?
As stoldark mentioned, this is not possible in a production environment at all. Since portal.properties's properties are loaded at portal start-up.
But for development you can use a tool like JRebel, some steps to configure it here. The only issue you would get with this tool is that it is paid ;-).
I know it is a very old thread but it may be helpful for someone who is looking for some type of work around
As we know there is no straight forward way for this but I did this by using java reflection and class loader.
Liferay Version : 6.x
//Loading the PropsUtil class by using PortalClassLoader
Class<?> prospsUtilClass = PortalClassLoaderUtil.getClassLoader().loadClass("com.liferay.portal.util.PropsUtil");
//getting the reload method of PropsUtil class
Method reloadMethod = prospsUtilClass.getMethod("reload", null);
//Invoking the static reload method
reloadMethod.invoke(null, null);
Reload method (re)loads the portal-ext properties to the portal so we can use new properties without restarting Liferay server.
This has also been asked in Liferay forums:
https://www.liferay.com/community/forums/-/message_boards/message/800954
But I am afraid that most properties are only read once during portal startup.
Usually, the use of a properties file as in this case has this drawback.
There's even an issue open at Liferay about this, but is still unresolved:
http://issues.liferay.com/browse/LEP-5579
If you create a hook to override portal properties, you will be able to change properties with just deploying the hook without restarting the Portal.
Be aware that you cannot modify all properties with a hook. For a list of the ones that you can modify, check out: https://docs.liferay.com/portal/6.2/definitions/.
I've just searched for reloading portal-ext.properties and landed here.
Ok - not a feature in Liferay.
So I'll use an old trick I like:
place custom properties in (liferay-tomcat-home)/conf/filename.properties
reload them whenever you want by
Properties customProperties = new Properties();
customProperties.load(new FileInputStream(new File(System.getProperty("catalina.base"), "conf/filename.properties")));
I must confess I haven't tried this in a Liferay-Portlet-Environment, but this system property ("catalina.base") should be available in this context, at least by using some Liferay-Helper-Class.
Some of the Liferay classes read their properties when initialising static field constants. E.g.:
public static final boolean ENABLED = GetterUtil.getBoolean(
PropsUtil.get(DynamicCSSFilter.class.getName()));
Basically, it is possible to reload the properties (eg via script in control-panel), but all those static constants will remain.
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?