Does anyone have a suggestion on a better way to intercept a properties with Castle DynamicProxy?
Specifically, I need the PropertyInfo that I'm intercepting, but it's not directly on the IInvocation, so what I do is:
public static PropertyInfo GetProperty(this MethodInfo method)
{
bool takesArg = method.GetParameters().Length == 1;
bool hasReturn = method.ReturnType != typeof(void);
if (takesArg == hasReturn) return null;
if (takesArg)
{
return method.DeclaringType.GetProperties()
.Where(prop => prop.GetSetMethod() == method).FirstOrDefault();
}
else
{
return method.DeclaringType.GetProperties()
.Where(prop => prop.GetGetMethod() == method).FirstOrDefault();
}
}
Then in my IInterceptor:
public void Intercept(IInvocation invocation)
{
bool doSomething = invocation.Method
.GetProperty()
.GetCustomAttributes(true)
.OfType<SomeAttribute>()
.Count() > 0;
}
Generally this is not available. DynamicProxy intercepts methods (incl. getters and setters), and it does not care about properties.
You could optimize this code a bit by making the interceptor IOnBehalfAware (see here) and discovering the method->property mapping upfront.
Related
I've written an CustomResourceHandler to add a version number to my js and css files, which works fine, but all primefaces resources get a double version number now.
Without CustomResourceHandler:
javax.faces.resource/jquery/jquery-plugins.js.xhtml?ln=primefaces&v=6.0.17
With CustomResourceHandler:
javax.faces.resource/jquery/jquery-plugins.js.xhtml?ln=primefaces&v=6.0.17&v=6.0.17
My CustomResourceHandler:
public class ExtendedResourceHandler extends PrimeResourceHandler {
public ExtendedResourceHandler(ResourceHandler wrapped) {
super(wrapped);
}
#Override
public Resource createResource(String resourceName, String libraryName) {
if (!org.primefaces.util.Constants.LIBRARY.equalsIgnoreCase(libraryName)
&& !org.primefaces.extensions.util.Constants.LIBRARY.equalsIgnoreCase(libraryName) && !"javax.faces".equalsIgnoreCase(libraryName) && resourceName != null
&& (resourceName.endsWith(".css") || resourceName.endsWith(".js"))) {
final Resource resource = super.createResource(resourceName, libraryName);
if (resource == null) {
return null;
}
return new ResourceWrapper() {
#Override
public String getRequestPath() {
String resultPath = super.getRequestPath();
resultPath += (resultPath.contains("?") ? "&" : "?") + "version=V6326";
return resultPath;
}
#Override
public Resource getWrapped() {
return resource;
}
};
} else {
return super.createResource(resourceName, libraryName);
}
}
}
faces-config.xml:
<resource-handler>de.sync4.cockpit.web.beans.resourcehandler.ExtendedResourceHandler</resource-handler>
Because of that problem I can't get the pe:ckEditor to work, because it can't find necessary resources. Any idea what's wrong with my Handler?
Found the Problem. I needed to extend the ResourceHandlerWrapper, not the PrimeResourceHandler.
I also have an ExtendedBeanELResolver. I had to return null there if the base object is an instance of my custom handler.
Maybe abstract typed factories are not an easy point to start with Windsor (2.5.3 if it matters) but I've got to do it anyway.
I'm trying to build a factory giving back processors depending on message type. So far i've scavenged from different places following code:
public class Complicato
{
public static void Do(string[] args)
{
IKernel kernel = new DefaultKernel();
IWindsorContainer container = new WindsorContainer();
kernel.AddFacility<TypedFactoryFacility>();
container.Install();
container.Register(
Component.For<HandlerSelector, ITypedFactoryComponentSelector>(),
AllTypes.FromThisAssembly().BasedOn(typeof(ITrier<>))
.WithService.Base().Configure(conf => conf.LifeStyle.Is(LifestyleType.Transient)),
Component.For<Factor>(),
Component.For<ITryFactory>().AsFactory(c => c.SelectedWith<HandlerSelector>()).LifeStyle.Singleton);
var factor = container.Resolve<Factor>();
var factory = container.Resolve<ITryFactory>();
}
}
public class HandlerSelector : DefaultTypedFactoryComponentSelector
{
protected override Type GetComponentType(MethodInfo method, object[] arguments)
{
return typeof(ITrier<>).MakeGenericType(arguments[0].GetType());
}
}
public class Factor
{
private ITryFactory factory;
public void Try(IWhat onto)
{
factory.GetTrier(onto).Try(onto);
}
}
public interface ITryFactory
{
ITrier<IWhat> GetTrier(IWhat onto);
void Release(object elem);
}
public interface IWhat { }
public interface ITrier<in TWhat> where TWhat : IWhat
{
void Try(TWhat input);
}
public class TrierYes : ITrier<WhatYes>
{
public void Try(WhatYes input) { Console.WriteLine("Yes? " + input.Aye()); }
}
public class TrierNo : ITrier<WhatNot>
{
public void Try(WhatNot input) { Console.WriteLine("No? " + input.Naa()); }
}
public class WhatYes : IWhat
{
public bool Aye() { return true; }
}
public class WhatNot : IWhat
{
public bool Naa() { return false; }
}
Main problem here is that id doesn't work. First I get Factor with factory of null and then as a consequence trying to resolve factory explicitely gives me ComponentActivator: could not proxy Factories.Complex.ITryFactory with inner message of The interceptor Castle.TypedFactory.Interceptor could not be resolved and "Keys (components with specific keys) - Castle.TypedFactory.Interceptor which was not registered" in container. I don't even know if the Handler selector works, it's not in question so far.
If I make ITrier not generic - it suddenly starts working but it's definitely not what I'm trying to achieve.
So do I make some silly beginners mistake in Windsor configuration or misunderstand the idea of typed factory?
For completeness sake, here's the exception message:
Castle.MicroKernel.ComponentActivator.ComponentActivatorException was unhandled
Message=ComponentActivator: could not proxy Factories.Complex.ITryFactory
Source=Castle.Windsor
StackTrace:
at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstance(CreationContext context, Object[] arguments, Type[] signature) in e:\OSS.Code\Castle.Windsor\src\Castle.Windsor\MicroKernel\ComponentActivator\DefaultComponentActivator.cs:line 166
InnerException: Castle.MicroKernel.Resolvers.DependencyResolverException
Message=The interceptor Castle.TypedFactory.Interceptor could not be resolved
Source=Castle.Windsor
StackTrace:
at Castle.Core.InterceptorReference.Castle.MicroKernel.IReference<Castle.DynamicProxy.IInterceptor>.Resolve(IKernel kernel, CreationContext context) in e:\OSS.Code\Castle.Windsor\src\Castle.Windsor\Core\InterceptorReference.cs:line 142
And the winner is
container.AddFacility<TypedFactoryFacility>(); // good code
instead of
kernel.AddFacility<TypedFactoryFacility>(); // bad code
Now I only have the issues of not injected factory and improper HandlerSelector.
NullReference was solved by introducing explicit initializing constructor to the Factor. I don't know why I thought it works without.
Final version of the handler interface is following:
public interface ITrier<out TWhat> where TWhat: IWhat
{
void Try(IWhat input);
}
To permit covariance. Not über-elegant as requires unnecessary cast and handlers loosen their typedness. But this is cruel reality. You're either co or contra-variant.
public interface IRepository<T>// : IDisposable
where T : IEntity
{
IQueryable<T> GetAll();
void Save(T entity);
void Delete(int id);
void Delete(T entity);
}
public abstract class RepositoryBase<T, TDb> : IRepository<T>
where T : IEntity
where TDb : class, IDbEntity, new()
{
protected abstract Table<TDb> GetTable();
public void Delete(int id)
{
TDb dbEntity = GetDbEntity(id);
if (dbEntity == null)
{
throw new MyException(...);
}
GetTable().DeleteOnSubmit(dbEntity);
Context.SubmitChanges();
}
// and other methods...
}
For now it is necessary to implement method that deletes entities by expression. I would like to have the following method in IRepository:
void DeleteWhere(Expression<Func<IEntity, bool>> exprFoeBusinessEntity);
The problem here is that implementation would look like this:
void DeleteWhere(Expression<Func<IEntity, bool>> exprFoeBusinessEntity);
{
Expression<Func<IDbEntity, bool>> exprFoeDbEntity
= exprWhere=> ... // How to convert exprFoeBusinessEntity into exprFoeDbEntity
GetTable().DeleteAllOnSubmit(GetTable().Where(exprForDbEntity)));
}
And I don't know how to convert expression for business entities into expression for db-entities...
I could easily change method to accept expression with db-entities, but I would like my Repository to hide DBEntities inside.
Please advise. Any thoughts are welcome.
P.S. I am working with .NET 3.5 (but solutions for 4.0 are also acceptable), ORM - Linq2Sql
Guess, I've found a good solution, here is a new method for RepositoryBase class:
public void Delete(IQueryable<T> entities)
{
IQueryable<TDb> dbEntities = GetTable()
.Where(
dbEntity => entities.Where(entity => entity.Id == dbEntity.Id).Count() > 0
)
;
GetTable().DeleteAllOnSubmit(dbEntities);
}
Please point me if you see any drawbacks here.
Castle Windsor 2.5. This fails. Why? Is it designated beahvior or a bug? Seems sub dependency resolvers are not even queried when resolving top-level services.
class Program
{
class Resolver :ISubDependencyResolver
{
public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
{
return new Program();
}
public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
{
return dependency.TargetType == typeof (Program);
}
}
[STAThread]
static void Main()
{
var container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(new Resolver());
var xxx = container.Resolve<Program>();
}
}
These are sub dependency resolvers. They resolve dependencies, not root services. What are you really trying to do? Why not register the object upfront?
Every programmer ends up with a set of utility classes after a while. Some of them are true programming pearls and they are reused in several of your projects. For example, in java:
class Separator {
private String separator;
private boolean called;
public Separator(String aSeparator) {
separator = aSeparator;
called = false;
}
#Override
public String toString() {
if (!called) {
called = true;
return "";
} else {
return separator;
}
}
}
and:
public class JoinHelper {
public static <T> String join(T... elements) {
return joinArray(" ", elements);
}
public static <T> String join(String separator, T... elements) {
return joinArray(separator, elements);
}
private static <T> String joinArray(String sep, T[] elements) {
StringBuilder stringBuilder = new StringBuilder();
Separator separator = new Separator(sep);
for (T element : elements) {
stringBuilder.append(separator).append(element);
}
return stringBuilder.toString();
}
}
What is your most reused class?
System.Object - almost all my types extend it.
A utility class that has logging and email functionality. An extensions class that contains extension methods. A reporting class that basically harness the reporting services web service and makes it easy to stream reports as excel, pdf, etc.
Examples...
1.) Utility Class (static)
public static void LogError(Exception ex)
{
EventLog log = new EventLog();
if (ex != null)
{
log.Source = ConfigurationManager.AppSettings["EventLog"].ToString();
StringBuilder sErrorMessage = new StringBuilder();
if (HttpContext.Current.Request != null && HttpContext.Current.Request.Url != null)
{
sErrorMessage.Append(HttpContext.Current.Request.Url.ToString() + System.Environment.NewLine);
}
sErrorMessage.Append(ex.ToString());
log.WriteEntry(sErrorMessage.ToString(), EventLogEntryType.Error);
}
}
2.) Extensions Class
public static IEnumerable<TSource> WhereIf<TSource>(this IEnumerable<TSource> source, bool condition, Func<TSource, bool> predicate)
{
if (condition)
return source.Where(predicate);
else
return source;
}
public static short getLastDayOfMonth(short givenMonth, short givenYear)
{
short lastDay = 31;
switch (givenMonth)
{
case 4:
case 6:
case 9:
case 11:
lastDay = 30;
break;
case 2:
if ((int)givenYear % 4 == 0)
{
lastDay = 29;
}
else
{
lastDay = 28;
}
break;
}
return lastDay;
}
Most reused but boring:
public static void handleException(Exception e) throws RuntimeException {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
throw new RuntimeException(e); //NOPMD
}
Less boring (also methods for building lists and sets):
/**
* Builds a Map that is based on the Bean List.
*
* #param items Bean List items
* #param keyField Bean Field that will be key of Map elements (not null)
* #return a Map that is based on the Bean List
*/
#SuppressWarnings("unchecked")
public static <T, K> Map<K, T> buildMapFromCollection(final Collection<T> items,
boolean linkedMap,
final String keyField,
final Class<K> keyType) {
if (items == null) {
return Collections.emptyMap();
}
if (keyField == null) {
throw new IllegalArgumentException("KeyField is null");
}
final Map<K, T> result;
if (linkedMap) {
result = new LinkedHashMap<K, T>();
} else {
result = new HashMap<K, T>();
}
BeanMapper mapper = null;
for (final T item : items) {
if (mapper == null) {
mapper = new BeanMapper(item.getClass());
}
final K key = (K) mapper.getFieldValue(item, keyField);
result.put(key, item);
}
return result;
}
Logger class: Which logs the flow of control in a log file.
Configuration Reader/Setter: which reads the configuration from ini/xml file and sets the environment of the application
Most reused? Hmmm...
boost::shared_ptr<> with boost::weak_ptr<>
probably most reused (also probably most bang-for-buck ratio)
Globals
Just a simple class with static DBConnString, and a few other app wide settings.
Have reused the simple file in about 2 dozen projects since working with .Net
A ConcurrentDictionary I wrote, which I now seem to use everywhere (I write lots of parallel programs)