Archive

Archive for the ‘.NET Framework’ Category

Running C#/.NET code from Cloud 9 IDE

March 16, 2015 Leave a comment

I was experimenting with Cloud 9 IDE mainly for remote coding interviews.

I also wanted to see if I could add C# support. C# syntax highlighting was already supported in Cloud 9. Mono is also pre installed in the Cloud 9 Environment.

All I had to do was add a custom runner to use mcs command line compiler for mono.

I am a complete newbie when it comes to ubuntu / bash etc., so please bear with if there are any script issues with the runner.

You can configure a custom runner using this json:

{
    "cmd" :  [
        "bash",
        "--login",
        "-c",
        "mcs '*.cs' -out:'$project_path$project_name.exe' $args;mono '$project_path$project_name.exe' $args"
    ],
    "info" : "Started $project_path$project_name",
    "env" : {},
    "selector" : "source.cs"
}
Categories: .NET Framework Tags: , , , ,

Technology Selection, Life of Microsoft Frameworks and lessons learned

March 29, 2011 3 comments

When you are choosing a technology / framework from a specific Vendor (Microsoft in this case) for a product development effort, you definitely expect the technology / framework to have a long life and continue to receive due investment and attention from the Vendor.

Not only for Product Development effort, if you are betting your career on a Microsoft Technology / Framework (which is a wrong in the first place, balancing your portfolio is very important) proceed with caution.

We all know these kind of stories when we read them.

ASP.NET Web forms to ASP.NET MVC, Yeah Yeah I know the typical Microsoft answer to these kind of strategic shifts. It is not dead yada yada yada.

http://weblogs.asp.net/despos/archive/2009/10/01/the-dead-end-of-web-forms.aspx

Linq to Sql to ADO.NET Entity Framework

Moving forward, Microsoft is committing to supporting both technologies as important parts of the .NET Framework, adding new features that meet customer requirements. We do, however, expect that the bulk of our overall investment will be in the Entity Framework,

http://msdn.microsoft.com/en-us/data/bb525059.aspx#Q3

http://blogs.msdn.com/b/adonet/archive/2008/10/29/update-on-linq-to-sql-and-linq-to-entities-roadmap.aspx

The same political management speak and yeah it is not dead.

.NET Remoting to .NET WCF

WCF to WCF Web HTTP

Silverlight for Cross Platform Web Development to HTML5 (oops HTML otherwise the whatwg folks will be angry).

Silverlight Questions

Where our strategy has shifted since we first started working on Silverlight is that the number of Internet connected devices out there in the world has increased significantly in the last 2 years (not just with phones, but also with embedded devices like TVs), and trying to get a single implementation of a runtime across all of them is no longer really practical (many of the devices are closed platforms that do not allow extensibility).  This is true for any single runtime implementation – whether it is Silverlight, Flash, Java, Cocoa, a specific HTML5 implementation, or something else.  If people want to have maximum reach across *all* devices then HTML will provide the broadest reach (this is true with HTML4 today – and will eventually be true with HTML5 in the future).  One of the things we as a company are working hard on is making sure we have the best browser and HTML5 implementation on Windows devices through the great work we are doing with IE9.

This by no means should be interpreted as Silverlight not being important.  We all know the importance of having the richest possible experiences for key platforms and form-factors, and the value that consumers (both end-users and enterprise) attribute to it. This is not just a true statement for Microsoft platforms – but has obviously been demonstrated by many others as well (Apple being an example).  Silverlight is a strategic technology from Microsoft that enables developers to build those, and we think our investments and focus (in particular with the above three areas) provides us with an incredibly compelling and differentiated platform to do so.

The Managed Extensibility and Add-In Framework which kind of disappeared.

What prompted this post suddenly was the information I read on the net about the future of WPF.

The rise and fall of the Microsoft UX platform Part 1

The rise and fall of the Microsoft UX platform Part 2

The rise and fall of the Microsoft UX platform Part 3

The rise and fall of the Microsoft UX platform Part 4

WPF has no Product Manager

Hey Scott WPF isn’t dead he just said so

WPF Lip Service at it again

WPF vNext

WPF Dead?  Silverlight Dead?

*Dead* is an over dramatic and vague term.  BUT it does make one lend an
ear. The better questions to ask IMO, are "Is WPF winding down
for maintenance mode?" or "What is Silverlight’s place on the web with
Microsoft’s HTML5 push and where is it’s place on the desktop given it’s not
designed as a full featured desktop technology?"

You can look at WPF’s new features and enhancements from 3.0 – 4.0 and come
up with a huge list of goodies.  Beyond just new controls and bugfixes, we
need to look at changes to the runtime because those changes ultimately move
the bar higher in the context of what is possible with WPF in the context of
making a competitive (as in iPad) UX.

Microsoft has known of WPF’s performance problems since the first time they
wrote a line of code for it.  You will be hard pressed to find a customer
that hasn’t complained about perf issues.  And you will not have gone to a
PDC in the last few years and not hear folks bring this up to the WPF team.
This is 3rd party info by now, but I’ve been told the issues I have noted
have been brought up internally, only to be disregarded.  Why?  It’s only my
guess when I say "time and resources."  But where have all the
development *resources
*gone?

Silverlight has pretty much taken over Microsoft’s spotlight in terms of UX
platform.  If you look at they history, they actually started on WPF/E even
before WPF was RTM.  They started on Silverlight before they even FIXED WPF!
They jumped on their own bandwagon, maybe with aims of taking over the rich
web from folks like Adobe.  Now with HTML5,* I don’t even think Microsoft
really knows what it’s going to do with Silverlight*.

Fix WPF

What should we do as a developer in the Microsoft Stack?

The lessons for us as passionate developers on the Microsoft Technology Stack –

  • Treat the new technologies / frameworks that come out of Microsoft with a grain of salt. This is especially true if the framework does the opposite of what community wisdom is (example, the complex page lifecycle of asp.net and stateful model of web development using viewstate)
  • Invest on open source alternatives if any (ex: use NHibernate over Linq to Sql and you do not give a damn when Microsoft declares Linq to Sql dead – oh it is not dead I know).
  • Invest to learn what other (non Microsoft) communities are doing in similar frameworks / technologies
  • I wish the ALT.NET movement is active, but you know the ALT.NET guys – see where they are headed.
  • The Core Microsoft platform hardly changes. A few examples – WCF’s ChannelModel is solid and can support WCF Traditional as well as WCF Web HTTP. Its the higher level abstraction of ServiceModel that went for wild swings. HttpHandlers and HttpModules are the same foundation on which ASP.NET Web Forms as well as ASP.NET MVC were built with. Invest in learning the core.
  • Invest in meta learning. Example: learning Linq to Sql / Entity Framework as a Object Relational Mapper at conceptual level than as a tool. UnitOfWork is UnitOfWork in any ORM, Concrete Table Inheritance Mapping is Concrete Table Inheritance Mapping in any ORM.

Delegates

January 25, 2011 1 comment

Imagine we are writing an Employees Collection class which has methods to filter by first name and department. The code looks so similar, can we somehow parameterize it to remove the duplication?

 

using System;
using System.Collections.Generic;

namespace CodingArchitect.Demos.Delegates
{
    public class EmployeesCollection
    {
        private readonly List<Employee> employees =
            new List<Employee>();

        public EmployeesCollection FilterByFirstName(string firstName)
        {
            var matches = new EmployeesCollection();
            foreach (var employee in employees)
            {
                if(string.Equals(employee.FirstName, firstName,
                    StringComparison.InvariantCulture))
                {
                    matches.Add(employee);
                }
            }
            return matches;
        }

        public EmployeesCollection FilterByDepartment(string department)
        {
            var matches = new EmployeesCollection();
            foreach (var employee in employees)
            {
                if (string.Equals(employee.Department, department,
                    StringComparison.InvariantCulture))
                {
                    matches.Add(employee);
                }
            }
            return matches;
        }

        private void Add(Employee employee)
        {
            employees.Add(employee);
        }
    }
    public class Employee
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Department { get; set; }
    }
}

Parameterize Method refactoring immediately comes to mind, only in this case the parameter should be a function which does the actual filtering. Passing functions as parameters is perfectly valid in C#. Now the condition alone can be passed as a delegate to the filter method. I am reusing the Predicate<T> delegate defined in the BCL. This is exactly what the FindAll method on the List<T> type in BCL does.

 

using System;
using System.Collections.Generic;

namespace CodingArchitect.Demos.Delegates
{
    public class EmployeesCollection
    {
        private readonly List<Employee> employees =
            new List<Employee>();

        public EmployeesCollection Filter(Predicate<Employee> condition)
        {
            var matches = new EmployeesCollection();
            foreach (var employee in employees)
            {
                if (condition(employee))
                {
                    matches.Add(employee);
                }
            }
            return matches;
        }

        private void Add(Employee employee)
        {
            employees.Add(employee);
        }
    }
    public class Employee
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Department { get; set; }
    }
}

The condition predicate can now be passed from the call site using a delegate (syntactic sugar like anonymous delegates, lambda expressions make it easier further).

Mike is doing a session @ the Orlando Code Camp

March 23, 2010 Leave a comment

If you are a .NET Developer living in/near Orlando, do not miss this session in Orlando Code Camp.

http://www.orlandocodecamp.com/Agenda.aspx/SessionDetail/5e6dc9ed-e2fc-4e2b-974b-b2cf6a800c17

Having worked with Mike for 3 years on the Model Driven Code Generation, I highly recommend it.

Categories: .NET Framework

Embedded Web Resources related Javascript errors

September 2, 2009 Leave a comment

It is sort of a long rant, feel free to jump to the end if you want to read the findings alone.

We had been running into this issue for more than an year now. I have been postponing getting to the bottom of the issue because we found some solution which works. We did not know why. A healthy prod by my client forced me research on the issue further.

The problem: Javascripts from embedded resources within assemblies were not getting downloaded and we used to get errors like ‘YAHOO’ is undefined, ‘xyz..’ is undefined etc. Initially I was thinking that the assembly has gone corrupt during the file transfer and used to retransfer the assembly to the server. And it used to work. Sometimes even a retransfer of file doesn’t work. After that we tried using reflector on the so called ‘corrupt’ assembly, but it opened like a charm indicating the file hasn’t gone corrupt. We also used to zip the files and when we transfer the files without zipping things used to work.

We thought the problem was with the zipping tool used to create the zip file and tried different options but in vain. A uncompressed file transferred directly used to work where as a zipped file fails, even though it opens fine in reflector. After some frantic searching yesterday I found the real reason. Initially I was on a wild goose chase around the lines of “The not so mysterious problem around webresource.axd”. I also created a sample to simulate the issue, but it vain.

Today morning I ran into “Web Resources Troubleshooting” from the Telerik folks. After reading the article I realized I had seen the error earlier in one of the dev boxes due to the date being in the future. I created a small sample to reproduce the issue and bingo! But it did not answer the question how retransfer was fixing the issues. We always zip the files and transfer the website. When 1 or 2 odd dlls go missing we do not zip that during the transfer.

The source and destination machines were in different time zones / times. The following conditions had to be true to get a the exception.

  • If the assembly build time happens to be within the time difference
  • and you zip the assembly for transferring
  • and for unzipping you use Windows Explorer Compressed folder feature 

the issue will occur

I did some more research and found the following facts.

Findings: Different applications use different philosophies when it comes to handling datetime stamps (Date Created & Date Modified). I tried the following applications

  • Windows explorer copy & paste to destination folder (from an ftp site).
  • Internet explorer saving the file from a web site
  • Windows Explorer Compressed folder feature to extract files.
  • 7Zip Extract files feature

The Windows Explorer Compressed folder extract files uses the timestamp of the source machine as is where as the other scenarios the local machine’s timestamp was used (I am overly simplifying it, you can try this on your own).

You can use Fiddler / firebug to see if any webresource / scriptresource are not getting downloaded. Here is the original error.

"Specified argument was out of the range of valid values. Parameter name: utcDate"
The assembly containing the embedded resources is probably built in the future (its last modified time is later than the current time). This can occur when deploying in a different time zone. In such case run the following command line statement (the commas and plus at the end are important!):
copy /b <path to assembly which is built in the future>+,,”

A little reflectoring lead me to AssemblyResourceLoader.GetAssemblyInfoWithAssertInternal which was using File.GetLastWriteTime rather than GetLastWriteTimeUtc. Is this the cause for the exception? I didn’t look deep enough to figure that.

Categories: .NET Framework

Linq to SQL Detached IQueryable / Disconnected Queries / Detached Criteria

March 11, 2008 2 comments

It has been a long time since I wrote something on technology. No, I am not becoming a non technical manager. It was just that I was lazy to write something up.

We are planning to standardize on LINQ’s IQueryable as the Query Object in our project. We had to choose between LINQ to SQL vs LINQ to Entities. Since LINQ to Entities / Entity Framework is still prerelease stuff we decided to check with LINQ to SQL first. A few issues which made us think before adopting LIINQ to SQL

  • No support for Disconnected Query Building (akin to NHibernate’s Detached Criteria)
  • No support for explicit detach of objects & object graphs from the DataContext (akin to NHibernate Detached entities / objects). You need to Serialize De-Serialize to detach an Entity Instance. Combine this with the WCF & LINQ Serialization issues with object graphs situation become further worse.
  • No support for attaching detached (detached by serialization / deserialization) object graphs.
  • IQueryable implementations & Expression classes are not serializable.
  • LINQ to SQL supports only Single Table Inheritance

But still LINQ to SQL query syntax is really cool. So we decided to use LINQ just for Querying and let our own framework handle the persistence mapping.

All of these limitations made me think of LINQ to SQL is just a cool Toy which cannot be used in production quality applications. In fact even some Microsoft folks have said something along these lines "LINQ to SQL supports rapid development of applications that query Microsoft SQL Server databases using objects that map directly to SQL Server schemas. LINQ to Entities supports more flexible mapping of objects to Microsoft SQL Server and other relational databases through extended ADO.NET Data Providers". From http://blogs.msdn.com/data/archive/2007/04/28/microsoft-s-data-access-strategy.aspx. LINQ to SQL is not for complex mapping scenarios. For complex Mapping scenarios use LINQ to Entities (it looks like L2E is going to bring in its own additional complexity).

How do we do disconnected LINQ queries which are going to be executed later by the LINQ to SQL provider / How do we simulate Detached Criteria using LINQ / Is there a Detached IQueryable implementation?

LINQ to SQL doesn’t support disconnected queries natively. As a workaround we were tempted to try IEnumerable.AsQueryable() which returns a EnumerableQuery on the client side (I know purists must be raising their eyebrows now that this should be done on the server side, in reality you cannot think all possible scenarios and let the client send in queries for scenarios that one hasn’t thought about). On the server side when we called DataContext.GetCommand(queryable) it started returning a SqlCommand with SELECT NULL AS [EMPTY] as CommandText.

Next we tried to create a disconnected query using a DataContext object initialized with an empty connection string on the client side. On the server side when we called DataContext.GetCommand(queryable) it started throwing an exception stating ‘The query contains references to items defined on a different data context’. Looks like LINQ to SQL wasn’t happy about a disconnected context no matter what you did.

We decided to use InterLinq‘s ExpressionConverter (actually it’s a slightly modified version of InterLinq’s ExpressionConverter inspired by Matt Waren‘s ExpressionVisitor) to rewrite the IQueryable references in the expression tree with the IQueryable created on the server side . We started getting another exception that Parameter ‘e’ not in scope. It looked like Matt’s code didn’t use the parameters collection returned by visit call inside the VisitLambda handler. Once that was fixed we were good to go.

    public class CloningExpressionVisitor
    {
        private readonly IQueryBinder queryBinder;
        private Dictionary<int, object> m_convertedObjects = new Dictionary<int, object>();
        private readonly Expression expressionToConvert;

        public CloningExpressionVisitor(Expression expression, IQueryBinder queryBinder)
        {
            this.queryBinder = queryBinder;
            expressionToConvert = expression;
        }

        public object Visit()
        {
            m_convertedObjects = new Dictionary<int, object>();
            return VisitResult(expressionToConvert);
        }

        /// <summary>
        /// Returns the value of the <see cref="Expression"/>.
        /// </summary>
        /// <param name="expression"><see cref="Expression"/> to visit.</param>
        /// <returns>Returns the value of the <see cref="Expression"/>.</returns>
        protected virtual object VisitResult(Expression expression)
        {
            if (expression == null)
            {
                return null;
            }
            if (m_convertedObjects.ContainsKey(expression.GetHashCode()))
            {
                return m_convertedObjects[expression.GetHashCode()];
            }

            object foundObject = null;

            if (expression is ConstantExpression)
            {
                foundObject = GetResultConstantExpression((ConstantExpression)expression);
            }
            else if (expression is MethodCallExpression)
            {
                foundObject = GetResultMethodCallExpression((MethodCallExpression)expression);
            }
            else
            {
                throw new NotImplementedException();
            }
            m_convertedObjects[expression.GetHashCode()] = foundObject;
            return foundObject;
        }

        protected virtual object GetResultConstantExpression(ConstantExpression expression)
        {
            object value = expression.Value;
            if (value == null)
            {
                return null;
            }
            else if (value is IQueryable)
            {
                return queryBinder.GetQueryBoundToNewProvider((value as IQueryable).ElementType);
            }
            return value;
        }

        protected virtual object GetResultMethodCallExpression( MethodCallExpression expression ) {
            return InvokeMethodCall( expression );
        }

        protected object InvokeMethodCall( MethodCallExpression ex ) {
            if( ex.Method.DeclaringType == typeof( Queryable ) ) {
                var args = new List<object>();
                for( int i = 0; i < ex.Arguments.Count; i++ ) {
                    Expression currentArg = ex.Arguments[i];
                    if( typeof( Expression ).IsAssignableFrom( currentArg.Type ) ) {
                        args.Add( ( (UnaryExpression) Visit( currentArg ) ).Operand );
                    }
                    else {
                        args.Add( VisitResult( currentArg ) );
                    }
                }
                return ex.Method.Invoke( ex.Object, args.ToArray() );
            }

            // If the method is not of DeclaringType "Queryable", it mustn't be invoked.
            // Without this check, we were able to delete files from the server disk
            // using System.IO.File.Delete( ... )!
            throw new SecurityException( string.Format( "Could not call method '{0}' of type '{1}'. Type must be Queryable.", ex.Method.Name, ex.Method.DeclaringType.Name ) );
        }

        public virtual Expression Visit(Expression exp)
        {
            if (exp == null)
                return exp;
            
            if (m_convertedObjects.ContainsKey(exp.GetHashCode()))
            {
                return (Expression)m_convertedObjects[exp.GetHashCode()];
            }

            Expression returnValue = null;

            switch (exp.NodeType)
            {
                case ExpressionType.Negate:
                case ExpressionType.NegateChecked:
                case ExpressionType.Not:
                case ExpressionType.Convert:
                case ExpressionType.ConvertChecked:
                case ExpressionType.ArrayLength:
                case ExpressionType.Quote:
                case ExpressionType.TypeAs:
                case ExpressionType.UnaryPlus:
                    returnValue = VisitUnary((UnaryExpression)exp);
                    break;
                case ExpressionType.Add:
                case ExpressionType.AddChecked:
                case ExpressionType.Subtract:
                case ExpressionType.SubtractChecked:
                case ExpressionType.Multiply:
                case ExpressionType.MultiplyChecked:
                case ExpressionType.Divide:
                case ExpressionType.Modulo:
                case ExpressionType.And:
                case ExpressionType.AndAlso:
                case ExpressionType.Or:
                case ExpressionType.OrElse:
                case ExpressionType.LessThan:
                case ExpressionType.LessThanOrEqual:
                case ExpressionType.GreaterThan:
                case ExpressionType.GreaterThanOrEqual:
                case ExpressionType.Equal:
                case ExpressionType.NotEqual:
                case ExpressionType.Coalesce:
                case ExpressionType.ArrayIndex:
                case ExpressionType.RightShift:
                case ExpressionType.LeftShift:
                case ExpressionType.ExclusiveOr:
                case ExpressionType.Power:
                    returnValue = VisitBinary((BinaryExpression)exp);
                    break;
                case ExpressionType.TypeIs:
                    returnValue = VisitTypeIs((TypeBinaryExpression)exp);
                    break;
                case ExpressionType.Conditional:
                    returnValue = VisitConditional((ConditionalExpression)exp);
                    break;
                case ExpressionType.Constant:
                    returnValue = VisitConstant((ConstantExpression)exp);
                    break;
                case ExpressionType.Parameter:
                    returnValue = VisitParameter((ParameterExpression)exp);
                    break;
                case ExpressionType.MemberAccess:
                    returnValue = VisitMemberAccess((MemberExpression)exp);
                    break;
                case ExpressionType.Call:
                    returnValue = VisitMethodCall((MethodCallExpression)exp);
                    break;
                case ExpressionType.Lambda:
                    returnValue = VisitLambda((LambdaExpression)exp);
                    break;
                case ExpressionType.New:
                    returnValue = VisitNew((NewExpression)exp);
                    break;
                case ExpressionType.NewArrayInit:
                case ExpressionType.NewArrayBounds:
                    returnValue = VisitNewArray((NewArrayExpression)exp);
                    break;
                case ExpressionType.Invoke:
                    returnValue = VisitInvocation((InvocationExpression)exp);
                    break;
                case ExpressionType.MemberInit:
                    returnValue = VisitMemberInit((MemberInitExpression)exp);
                    break;
                case ExpressionType.ListInit:
                    returnValue = VisitListInit((ListInitExpression)exp);
                    break;
                default:
                    throw new Exception(string.Format("Unhandled expression type: '{0}'", exp.NodeType));
            }

            m_convertedObjects.Add(exp.GetHashCode(), returnValue);
            return returnValue;
        }

        protected virtual MemberBinding VisitBinding(MemberBinding binding)
        {
            switch (binding.BindingType)
            {
                case MemberBindingType.Assignment:
                    return this.VisitMemberAssignment((MemberAssignment)binding);
                case MemberBindingType.MemberBinding:
                    return this.VisitMemberMemberBinding((MemberMemberBinding)binding);
                case MemberBindingType.ListBinding:
                    return this.VisitMemberListBinding((MemberListBinding)binding);
                default:
                    throw new Exception(string.Format("Unhandled binding type '{0}'", binding.BindingType));
            }
        }

        protected virtual ElementInit VisitElementInitializer(ElementInit initializer)
        {
            ReadOnlyCollection<Expression> arguments = this.VisitExpressionList(initializer.Arguments);
            return Expression.ElementInit(initializer.AddMethod, arguments);
        }

        protected virtual Expression VisitUnary(UnaryExpression u)
        {
            Expression operand = this.Visit(u.Operand);
            return Expression.MakeUnary(u.NodeType, operand, u.Type, u.Method);
        }

        protected virtual Expression VisitBinary(BinaryExpression b)
        {
            Expression left = this.Visit(b.Left);
            Expression right = this.Visit(b.Right);
            Expression conversion = this.Visit(b.Conversion);
            if (b.NodeType == ExpressionType.Coalesce && b.Conversion != null)
                return Expression.Coalesce(left, right, conversion as LambdaExpression);
            else
                return Expression.MakeBinary(b.NodeType, left, right, b.IsLiftedToNull, b.Method);

        }

        protected virtual Expression VisitTypeIs(TypeBinaryExpression b)
        {
            Expression expr = this.Visit(b.Expression);
            return Expression.TypeIs(expr, b.TypeOperand);
        }

        protected virtual Expression VisitConstant(ConstantExpression expression)
        {
            if (expression.Value == null)
            {
                return null;
            }
            return Expression.Constant(expression.Value);
        }

        protected virtual Expression VisitConditional(ConditionalExpression c)
        {
            Expression test = this.Visit(c.Test);
            Expression ifTrue = this.Visit(c.IfTrue);
            Expression ifFalse = this.Visit(c.IfFalse);
            return Expression.Condition(test, ifTrue, ifFalse);
        }

        protected virtual Expression VisitParameter(ParameterExpression p)
        {
            return Expression.Parameter(p.Type, p.Name);
        }

        protected virtual Expression VisitMemberAccess(MemberExpression m)
        {
            Expression exp = this.Visit(m.Expression);
            return Expression.MakeMemberAccess(exp, m.Member);
        }

        protected virtual Expression VisitMethodCall(MethodCallExpression m)
        {
            
            Expression obj = this.Visit(m.Object);
            IEnumerable<Expression> args = this.VisitExpressionList(m.Arguments);
            //switch (m.Method.Name)
            //{
            //    case "Where":
            //        args = new List<Expression>() { Expression.Constant(queryable, queryable.GetType()), this.Visit(m.Arguments[1]) };
            //        break;
            //}
            return Expression.Call(obj, m.Method, args);
        }

        protected virtual ReadOnlyCollection<Expression> VisitExpressionList(ReadOnlyCollection<Expression> original)
        {
            List<Expression> list = null;
            for (int i = 0, n = original.Count; i < n; i++)
            {
                Expression p = this.Visit(original[i]);
                if (list != null)
                {
                    list.Add(p);
                }
                else if (p != original[i])
                {
                    list = new List<Expression>(n);
                    for (int j = 0; j < i; j++)
                    {
                        list.Add(original[j]);
                    }
                    list.Add(p);
                }
            }
            if (list != null)
            {
                return list.AsReadOnly();
            }
            return original;
        }

        protected virtual MemberAssignment VisitMemberAssignment(MemberAssignment assignment)
        {
            Expression e = this.Visit(assignment.Expression);
            return Expression.Bind(assignment.Member, e);
        }

        protected virtual MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding binding)
        {
            IEnumerable<MemberBinding> bindings = this.VisitBindingList(binding.Bindings);
            return Expression.MemberBind(binding.Member, bindings);
        }

        protected virtual MemberListBinding VisitMemberListBinding(MemberListBinding binding)
        {
            IEnumerable<ElementInit> initializers = this.VisitElementInitializerList(binding.Initializers);
            return Expression.ListBind(binding.Member, initializers);
        }

        protected virtual IEnumerable<MemberBinding> VisitBindingList(ReadOnlyCollection<MemberBinding> original)
        {
            List<MemberBinding> list = null;
            for (int i = 0, n = original.Count; i < n; i++)
            {
                MemberBinding b = this.VisitBinding(original[i]);
                if (list != null)
                {
                    list.Add(b);
                }
                else if (b != original[i])
                {
                    list = new List<MemberBinding>(n);
                    for (int j = 0; j < i; j++)
                    {
                        list.Add(original[j]);
                    }
                    list.Add(b);
                }
            }
            if (list != null)
                return list;
            return original;
        }

        protected virtual IEnumerable<ElementInit> VisitElementInitializerList(ReadOnlyCollection<ElementInit> original)
        {
            List<ElementInit> list = null;
            for (int i = 0, n = original.Count; i < n; i++)
            {
                ElementInit init = this.VisitElementInitializer(original[i]);
                if (list != null)
                {
                    list.Add(init);
                }
                else if (init != original[i])
                {
                    list = new List<ElementInit>(n);
                    for (int j = 0; j < i; j++)
                    {
                        list.Add(original[j]);
                    }
                    list.Add(init);
                }
            }
            if (list != null)
                return list;
            return original;
        }

        protected virtual Expression VisitLambda(LambdaExpression lambda)
        {
            Expression body = this.Visit(lambda.Body);
            IEnumerable<ParameterExpression> parameters = VisitCollection<ParameterExpression>(lambda.Parameters);
            return Expression.Lambda(lambda.Type, body, parameters);
        }

        public IEnumerable<T> VisitCollection<T>(IEnumerable enumerable) where T : Expression
        {
            if (enumerable == null)
            {
                return null;
            }

            var returnValues = new List<T>();
            foreach (Expression expression in enumerable)
            {
                returnValues.Add((T)Visit(expression));
            }
            return returnValues;
        }

        protected virtual NewExpression VisitNew(NewExpression nex)
        {
            IEnumerable<Expression> args = this.VisitExpressionList(nex.Arguments);
            if (nex.Members != null)
                return Expression.New(nex.Constructor, args, nex.Members);
            else
                return Expression.New(nex.Constructor, args);
        }

        protected virtual Expression VisitMemberInit(MemberInitExpression init)
        {
            NewExpression n = this.VisitNew(init.NewExpression);
            IEnumerable<MemberBinding> bindings = this.VisitBindingList(init.Bindings);
            return Expression.MemberInit(n, bindings);
        }

        protected virtual Expression VisitListInit(ListInitExpression init)
        {
            NewExpression n = this.VisitNew(init.NewExpression);
            IEnumerable<ElementInit> initializers = this.VisitElementInitializerList(init.Initializers);
            return Expression.ListInit(n, initializers);
        }

        protected virtual Expression VisitNewArray(NewArrayExpression na)
        {
            IEnumerable<Expression> exprs = this.VisitExpressionList(na.Expressions);

            if (na.NodeType == ExpressionType.NewArrayInit)
            {
                return Expression.NewArrayInit(na.Type.GetElementType(), exprs);
            }
            else
            {
                return Expression.NewArrayBounds(na.Type.GetElementType(), exprs);
            }

        }

        protected virtual Expression VisitInvocation(InvocationExpression iv)
        {
            IEnumerable<Expression> args = this.VisitExpressionList(iv.Arguments);
            Expression expr = this.Visit(iv.Expression);
            return Expression.Invoke(expr, args);
        }

       }

    public class LinqToSqlBinder : IQueryBinder
    {
        private readonly DataContext dataContext;

        public LinqToSqlBinder(DataContext dataContext)
        {
            this.dataContext = dataContext;
        }

        #region IQueryBinder Members

        public IQueryable GetQueryBoundToNewProvider(Type type)
        {
            return dataContext.GetTable(type);
        }

        #endregion
    }

public interface IQueryBinder { IQueryable GetQueryBoundToNewProvider(Type type); }

public class LinqToObjectsBinder : IQueryBinder { private readonly IEnumerable objectSource; public LinqToObjectsBinder(IEnumerable objectSource) { this.objectSource = objectSource; } #region IQueryBinder Members public IQueryable GetQueryBoundToNewProvider(Type type) { return objectSource.AsQueryable(); } #endregion }

Categories: .NET Framework

SqlCacheDependency with Query Notifications

April 30, 2007 Leave a comment

If at all you have to get the SqlCacheDependency working with Query Notifications feature of SQL Server 2005, these links will provide a head start.
#1 Query Notifications in ADO.NET 2.0
#2 Using and Monitoring SQL 2005 Query Notification
Article #1 is just excellent in that it answers all the questions you get on how query notifications work.
Article #2 mentions how to debug the query notification infrastructure using the Profiler.
It a great feature but I really don’t know why its a pain to use. I am no API design expert but I could say something is wrong there…

Categories: .NET Framework