Provide an implementation to a typed factory's method - inversion-of-control

I have a typed factory interface as follows:
public interface ILogMessageFactory
{
ILogMessage Create(LogMessageType logMessageType, String text);
}
and I am registering it all follows:
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.AddFacility<TypedFactoryFacility>();
container.Register(
Component.For(typeof(ConsolePrompter)),
Component.For<ILogger>().ImplementedBy<ConsoleLogger>().LifeStyle.Transient,
Component.For<ILogMessageFactory>().AsFactory(),
Component.For<ILogMessage>().ImplementedBy<LogMessage>().LifeStyle.Transient
);
}
The problem is that I want to implement the ILogMessageFactory.Create method myself, to set a few things before I return.
I've tried the obvious naïve solution without any success:
Component.For<ILogMessageFactory>().ImplementedBy<LogMessageFactory>().AsFactory()
Am I approaching this wrong? Should I just keep all initialization in the constructor of the given object?

use ITypedFactoryComponentSelector if this is something that really belongs to the factory. Alternatively use .OnCreate() on the component the factory resolves

Related

how register an interface that has no implentation with autofac?

How you I register an interface that has no implentation using Autofac?
I want Autofac to use DynamicProxy to generate interface your me!
builder.RegisterType(typeof(IUserDao))
.AsImplementedInterfaces()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(SqlMapperInterceptor));
public class SqlMapperInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
//todo: mapper sql file and return data
}
}
There is currently no mechanism to achieve this through the DynamicProxy2 integration provided by Autofac, but it can still be done by registering the generated proxy interface with Autofac directly:
builder.Register(c =>
{
var proxyGen = new ProxyGenerator();
return proxyGen.CreateInterfaceProxyWithoutTarget<IUserDao>(new SqlMapperInterceptor());
})
.As<IUserDao>();
There must be something to intercept, otherwise it isn't interception. The solution is to create a dummy IUserDao implementation a.k.a. Null Object Pattern. This dummy cwn be registered as implementation in Autofac.

#Category in AutoBean

Am totally lost trying to understand the #Category annotation of AutoBean. Can somebody please tell me how exactly it can be used?
I went through the example in wiki as well. My doubt is like this.
Say I am having a proxy interface in the client side which extends entity proxy, and I want to insert a non setter/getter method in that interface, how can I do that?
#ProxyFor( value = CacheStrategy.class )
public interface CacheStrategyProxy extends EntityProxy
{
// setters and getters
CacheStrategyProxy fetchObject(int id);
}
#Category(CacheStrategyProxyCategory.class)
interface MyFactory extends AutoBeanFactory {
AutoBean<CacheStrategyProxy> fetchObject();
}
class CacheStrategyProxyCategory {
public static CacheStrategyProxy fetchObject (AutoBean<CacheStrategyProxy> instance, int id) {
// return data
}
}
Am writing all this in my CacheStrategyProxy file. But I still get the error "Only setters and getters allowed". Pardon me if I have done something silly here. I am totally new to this world.
#Category cannot be used with Request Factory (at least not currently).
Request Factory makes use of AutoBeans (and your proxies will be AutoBean instances) but the AutoBeanFactory (factories actually) is/are internal to the RequestFactory, and you cannot tweak them.

GWT Editor framework

Is there a way to get the proxy that editor is editing?
The normal workflow would be:
public class Class implments Editor<Proxy>{
#Path("")
#UiField AntoherClass subeditor;
void someMethod(){
Proxy proxy = request.create(Proxy.class);
driver.save(proxy);
driver.edit(proxy,request);
}
}
Now if i got a subeditor of the same proxy
public class AntoherClass implements Editor<Proxy>{
someMethod(){
// method to get the editing proxy ?
}
}
Yes i know i can just set the proxy to the Child editor with setProxy() after its creation, but i want to know if there is something like HasRequestContext but for the edited proxy.
This usefull when you use for example ListEditor in non UI objects.
Thank you.
Two ways you can get a reference to the object that a given editor is working on. First, some simple data and a simple editor:
public class MyModel {
//sub properties...
}
public class MyModelEditor implements Editor<MyModel> {
// subproperty editors...
}
First: Instead of implementing Editor, we can pick another interface that also extends Editor, but allows sub-editors (LeafValueEditor does not allow sub-editors). Lets try ValueAwareEditor:
public class MyModelEditor2 implements ValueAwareEditor<MyModel> {
// subproperty editors...
// ValueAwareEditor methods:
public void setValue(MyModel value) {
// This will be called automatically with the current value when
// driver.edit is called.
}
public void flush() {
// If you were going to make any changes, do them here, this is called
// when the driver flushes.
}
public void onPropertyChange(String... paths) {
// Probably not needed in your case, but allows for some notification
// when subproperties are changed - mostly used by RequestFactory so far.
}
public void setDelegate(EditorDelegate<MyModel> delegate) {
// grants access to the delegate, so the property change events can
// be requested, among other things. Probably not needed either.
}
}
This requires that you implement the various methods as in the example above, but the main one you are interested in will be setValue. You do not need to invoke these yourself, they will be called by the driver and its delegates. The flush method is also good to use if you plan to make changes to the object - making those changes before flush will mean that you are modifying the object outside of the expected driver lifecycle - not the end of the world, but might surprise you later.
Second: Use a SimpleEditor sub-editor:
public class MyModelEditor2 implements ValueAwareEditor<MyModel> {
// subproperty editors...
// one extra sub-property:
#Path("")//bound to the MyModel itself
SimpleEditor self = SimpleEditor.of();
//...
}
Using this, you can call self.getValue() to read out what the current value is.
Edit: Looking at the AnotherEditor you've implemented, it looks like you are starting to make something like the GWT class SimpleEditor, though you might want other sub-editors as well:
Now if i got a subeditor of the same proxy
public class AntoherClass implements Editor<Proxy>{
someMethod(){
// method to get the editing proxy ?
}
}
This sub-editor could implement ValueAwareEditor<Proxy> instead of Editor<Proxy>, and be guaranteed that its setValue method would be called with the Proxy instance when editing starts.
In your child editor class, you can just implement another interface TakesValue, you can get the editing proxy in the setValue method.
ValueAwareEditor works too, but has all those extra method you don't really need.
This is the only solution I found. It involves calling the context edit before you call the driver edit. Then you have the proxy to manipulate later.

MEF and IObservables

I have a singleton IObservable that returns the results of a Linq query. I have another class that listens to the IObservable to structure a message. That class is Exported through MEF, and I can import it and get asynchronous results from the Linq query.
My problem is that after initial composition takes place, I don't get any renotification on changes when the data supplied to the Linq query changes. I implemented INotifyPropertyChanged on the singleton, thinking it word make the exported class requery for a new IObservable, but this doesn't happen.
Maybe I'm not understanding something about the lifetime of MEF containers, or about property notification. I'd appreciate any help.
Below are the singleton and the exported class. I've left out some pieces of code that can be inferred, like the PropertyChanged event handlers and such. Suffice to say, that does work when the underlying Session data changes. The singleton raises a change event for UsersInCurrentSystem, but there is never any request for a new IObservable from the UsersInCurrentSystem property.
public class SingletonObserver: INotifyPropertyChanged
{
private static readonly SingletonObserver _instance = new SingletonObserver();
static SingletonObserver() { }
private SingletonObserver()
{
Session.ObserveProperty(xx => xx.CurrentSystem, true)
.Subscribe(x =>
{
this.RaisePropertyChanged(() => this.UsersInCurrentSystem);
});
}
public static SingletonObserverInstance { get { return _instance; } }
public IObservable<User> UsersInCurrentSystem
{
get
{
var x = from user in Session.CurrentSystem.Users
select user;
return x.ToObservable();
}
}
}
[Export]
public class UserStatus : INotifyPropertyChanged
{
private string _data = string.Empty;
public UserStatus
{
SingletonObserver.Instance.UsersInCurrentSystem.Subscribe(sender =>
{
//set _data according to information in sender
//raise PropertyChanged for Data
}
}
public string Data
{
get { return _data; } }
}
}
My problem is that after initial composition takes place, I don't get any renotification on changes when the data supplied to the Linq query changes.
By default MEF will only compose parts once. When a part has been composed, the same instance will be supplied to all imports. The part will not be recreated unless you explicitly do so.
In your case, if the data of a part change, even if it implements INotifyPropertyChanged, MEF will not create a new one, and you don't need to anyway.
I implemented INotifyPropertyChanged on the singleton, thinking it word make the exported class requery for a new IObservable
No.
Maybe I'm not understanding something about the lifetime of MEF containers, or about property notification.
Property notification allows you to react to a change in the property and has no direct effect on MEF. As for the container's lifetime, it will remain active until it is disposed. While it is still active, the container will keep references to it's compose parts. It's actually a little more complex than that, as parts can have different CreationPolicy that affects how MEF holds the part, I refer you to the following page: Parts Lifetime for more information.
MEF does allow for something called Recomposition. You can set it likewise:
[Import(AllowRecomposition=true)]
What this does tough is allow MEF to recompose parts when new parts are available or existing parts aren't available anymore. From what I understand it isn't what you are referring to in your question.

How to make JPA EntityListeners validate the existence of an interface

I am working in J2EE 5 using JPA, I have a working solution but I'm looking to clean up the structure.
I am using EntityListeners on some of the JPA objects I am persisting, the listeners are fairly generic but depend on the beans implementing an interface, this works great if you remember to add the interface.
I have not been able to determine a way to tie the EntityListener and the Interface together so that I would get an exception that lead in the right direction, or even better a compile time error.
#Entity
#EntityListener({CreateByListener.class})
public class Note implements CreatorInterface{
private String message;....
private String creator;
....
}
public interface CreatorInterface{
public void setCreator(String creator);
}
public class CreateByListener {
#PrePersist
public void dataPersist(CreatorInterface data){
SUser user = LoginModule.getUser();
data.setCreator(user.getName());
}
}
This functions exactly the way I want it to, except when a new class is created and it uses the CreateByListener but does not implement the CreatorInterface.
When this happens a class cast exception is thrown somewhere deep from within the JPA engine and only if I happen to remember this symptom can I figure out what went wrong.
I have not been able to figure a way to require the interface or test for the presence of the interface before the listener would be fired.
Any ideas would be appreciated.
#PrePersist
public void dataPersist(Object data){
if (!(data instanceof CreatorInterface)) {
throw new IllegalArgumentException("The class "
+ data.getClass()
+ " should implement CreatorInterface");
}
CreatorInterface creatorInterface = (CreatorInterface) data;
SUser user = LoginModule.getUser();
creatorInterface.setCreator(user.getName());
}
This does basically the same thing as what you're doing, but at least you'll have a more readable error message indicating what's wrong, instead of the ClassCastException.