static KVOObservableForProperty() { var monotouchAssemblyName = typeof(NSObject).Assembly.FullName; declaredInNSObject = new MemoizingMRUCache <Tuple <Type, string>, bool>( (pair, _) => { var thisType = pair.Item1; // Types that aren't NSObjects at all are uninteresting to us if (typeof(NSObject).IsAssignableFrom(thisType) == false) { return(false); } while (thisType != null) { if (thisType.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Any(x => x.Name == pair.Item2)) { // NB: This is a not-completely correct way to detect if // an object is defined in an Obj-C class (it will fail if // you're using a binding to a 3rd-party Obj-C library). return(thisType.Assembly.FullName == monotouchAssemblyName); } thisType = thisType.BaseType; } // The property doesn't exist at all return(false); }, RxApp.BigCacheLimit); }
public DefaultLogManager(IDependencyResolver dependencyResolver = null) { dependencyResolver = dependencyResolver ?? RxApp.DependencyResolver; loggerCache = new MemoizingMRUCache <Type, IFullLogger>((type, _) => { var ret = dependencyResolver.GetService <ILogger>() ?? defaultLogger; if (ret == null) { return(new WrappingFullLogger(defaultLogger, type)); } return(new WrappingFullLogger(ret, type)); }, RxApp.BigCacheLimit); }
public DefaultLogManager(IDependencyResolver dependencyResolver = null) { dependencyResolver = dependencyResolver ?? RxApp.DependencyResolver; loggerCache = new MemoizingMRUCache <Type, IFullLogger>((type, _) => { var ret = dependencyResolver.GetService <ILogger>(); if (ret == null) { throw new Exception("Couldn't find an ILogger. This should never happen, your dependency resolver is probably broken."); } return(new WrappingFullLogger(ret, type)); }, RxApp.BigCacheLimit); }
/// <summary> /// Constructs an ObservableAsyncMRUCache object. /// </summary> /// <param name="calculationFunc">The function that performs the /// expensive or asyncronous calculation and returns an async result - /// for CPU-based operations, Observable.Return may be used to return /// the result. /// /// Note that this function *must* return an equivalently-same result given a /// specific input - because the function is being memoized, if the /// calculationFunc depends on other varables other than the input /// value, the results will be unpredictable. /// </param> /// <param name="maxSize">The number of items to cache. When this limit /// is reached, not recently used items will be discarded.</param> /// <param name="maxConcurrent">The maximum number of concurrent /// asynchronous operations regardless of key - this is important for /// web-based caches to limit the number of concurrent requests to a /// server. The default is 5.</param> /// <param name="onRelease">This optional method is called when an item /// is evicted from the cache - this can be used to clean up / manage an /// on-disk cache; the calculationFunc can download a file and save it /// to a temporary folder, and the onRelease action will delete the /// file.</param> /// <param name="sched">The scheduler to run asynchronous operations on /// - defaults to TaskpoolScheduler</param> public ObservableAsyncMRUCache( Func <TParam, IObservable <TVal> > calculationFunc, int maxSize, int maxConcurrent = 5, Action <TVal> onRelease = null, IScheduler sched = null) { sched = sched ?? RxApp.TaskpoolScheduler; _callQueue = new SemaphoreSubject <int>(maxConcurrent, sched); _fetcher = calculationFunc; Action <IObservable <TVal> > release = null; if (onRelease != null) { release = new Action <IObservable <TVal> >(x => onRelease(x.First())); } _innerCache = new MemoizingMRUCache <TParam, IObservable <TVal> >((x, val) => { var ret = (IObservable <TVal>)val; return(ret); }, maxSize, release); }