0%

Add references to:

  • Autofac.dll (v3.1.1)
  • Autofac.Extras.DynamicProxy2.dll (v3.0.2)
  • Castle.Core.dll (Castle.Core 3.2.0 for .NETFramework v4.0 Client Profile)

#Create Interceptors#
Interceptors implement the Castle.DynamicProxy.IInterceptor interface. Here’s a simple interceptor example that logs method calls including inputs and outputs:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class LoggerClass : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("Calling method {0} with parameters {1}... ",
invocation.Method.Name,
string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()));

invocation.Proceed();

Console.WriteLine("Done: result was {0}.", invocation.ReturnValue);
}
}

#Register Interceptors with Autofac#
Interceptors must be registered with the container. You can register them either as typed services or as named services. If you register them as named services, they must be named IInterceptor registrations.

Which of these you choose depends on how you decide to associate interceptors with the types being intercepted.

1
2
3
4
5
6
// Named registration
builder.Register(c => new LoggerClass())
.Named<IInterceptor>("log-calls");

// Typed registration
builder.Register(c => new LoggerClass());

#Enable Interception on Types#
When you register a type being intercepted, you have to mark the type at registration time so Autofac knows to wire up that interception. You do this using the EnableInterfaceInterceptors() and EnableClassInterceptors() registration extensions.

1
2
3
4
5
6
ContainerBuilder cb = new ContainerBuilder();
cb.RegisterType<SomeType>()
.As<ISomeInterface>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(LoggerClass));
cb.Register(c => new LoggerClass());

Under the covers, EnableInterfaceInterceptors() creates an interface proxy that performs the interception, while EnableClassInterceptors() dynamically subclasses the target component to perform interception of virtual methods.

Both techniques can be used in conjunction with the assembly scanning support, so you can configure batches of components using the same methods.

Here’s the easiest way to accomplish deploying folders to the TestResults folder:

  1. Right click on the .testrunconfig file in your solution explorer. For me, its LocalTestRun.testrunconfig.
  2. Select Open With and select XML editor
  3. Add a deployment item, specifying the relative path as the file name and an outputdirectory value of the directory name. In my example, I want to deploy everything in the configuration directory to a folder called configuration in the testrun folder, so I’ve added the following entry:
1
2
3
<Deployment>
<DeploymentItem filename="Services\Identity\Claim\ClaimService.Test\configuration\" outputDirectory="configuration\" ></DeploymentItem>
</Deployment>

Now when my tests execution, Visual Studio copies over all my configuration file entries and is able to load the app.config file successfully.

1
2
3
[NullReferenceException: Object reference not set to an instance of an object.]
System.Web.Mvc.<ConvertResults>d__2.MoveNext() +105
System.Web.Mvc.<Validate>d__1.MoveNext() +1050 System.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) +404

Please check your Validate function code in xxxModel (inherited IValidatableObject). You should not return null value.

1
2
3
4
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
return null; // this is error code
}

Using morelinq you can use DistinctBy:

1
myList.DistinctBy(x => x.id);

Otherwise, you can use a group:

1
2
myList.GroupBy(x => x.id)
.Select(g => g.First());

Or you can use linq syntax

1
2
3
distinctData = from tb1 in myList
group tb1 by tb1.id into g
select g.First();

You can create custom extension method:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static class EnumerableExtender
{
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
HashSet<TKey> seenKeys = new HashSet<TKey>();
foreach (TSource element in source)
{
var elementValue = keySelector(element);
if (seenKeys.Add(elementValue))
{
yield return element;
}
}
}
}

Would be better to write a lot of use.

1
distinctDatas = myList.DistinctBy(person => person.Name);

Here’s a Website.targets file you can include in unit testing solution. It (re)compiles website only when App_Code changes. Just add something in Test Project like

1
2
3
4
5
6
7
<PropertyGroup>
<WebsiteName>*MyWebsite*</WebsiteName>
<WebsitePath>..</WebsitePath>
</PropertyGroup>
<Import Project="$(ProjectDir)\Website.targets" ></Import>
<Target Name="BeforeBuild" DependsOnTargets="CompileWebsite">
</Target>

to your .csproj, customizing WebsiteName and WebsitePath and you should be ready to create Website.targets file in Test Project Folder:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8"?>
<!--
Target that compiles Website's App_Code to be used for testing
-->
<Project DefaultTargets="CompileWebsite" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<AppCodeFiles Include="$(WebsitePath)\$(WebsiteName)\App_Code\**\*.*" ></AppCodeFiles>
</ItemGroup>
<Target Name="CompileWebsite" Inputs="@(AppCodeFiles)" Outputs="$(ProjectDir)\PrecompiledWeb\bin\App_Code.dll">
<AspNetCompiler VirtualPath="$(WebsiteName)" PhysicalPath="$(WebsitePath)\$(WebsiteName)" TargetPath="$(ProjectDir)\PrecompiledWeb" Force="true" Debug="true" ></AspNetCompiler>
</Target>
<Target Name="CleanWebsite">
<RemoveDir Directories="$(WebsitePath)\$(WebsiteName)\PrecompiledWeb" ></RemoveDir>
</Target>
</Project>

In Web.config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<configuration>
<system.web>
<authentication mode="Forms">
<forms defaultUrl="~/Home/Index/" loginUrl="~/Home/Login/" timeout="30" ></forms>
</authentication>
<authorization>
<deny users="?"></deny>
</authorization>
</system.web>
<location path="Scripts">
<system.web>
<authorization>
<allow users="*"></allow>
</authorization>
</system.web>
</location>
</configuration>

Create LoginViewModel.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class LoginViewModel : IValidatableObject
{
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string ReturnUrl { get; set; }

[DisplayFormat(ConvertEmptyStringToNull = false)]
[Required]
public string UserName { get; set; }

[DisplayFormat(ConvertEmptyStringToNull = false)]
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }

[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
return null;
}
}

Create HomeController.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class HomeController : Controller
{
[AllowAnonymous]
public ActionResult Login(string ReturnUrl)
{
//ReturnUrl: url that is before user login
var vm = new LoginViewModel() { ReturnUrl = ReturnUrl };
return View(vm);
}

[AllowAnonymous]
[HttpPost]
public ActionResult Login(LoginViewModel model)
{
//
if( !ModelState.IsValid )
{
return View(model);
}

//todo check login account and password
if (false)
{
...
}

FormsAuthentication.RedirectFromLoginPage(model.UserName, false);
return Redirect(FormsAuthentication.GetRedirectUrl(model.UserName, false));
}
[AllowAnonymous]
public ActionResult Logout()
{
Session.Abandon();
FormsAuthentication.SignOut();
return RedirectToAction("Login", "Home");
}

In Home/Login.cshtml

1
2
3
4
5
6
7
8
9
10
@using (Html.BeginForm("Login", "Home", new { ReturnUrl=Model.ReturnUrl }, FormMethod.Post, new { autocomplete="off" }))
{
@Html.TextBoxFor(m => m.UserName)
@Html.ValidationMessageFor(m => m.UserName)
<br />
@Html.PasswordFor(m => m.Password)
@Html.ValidationMessageFor(m => m.Password)
<br />
<input type="submit" value="Login" />
}

After I rename VS.NET 2013 Project Name, I had this “The ‘Microsoft.VisualStudio.Editor.Implementation.EditorPackage’ package did not load correctly.” error message when I started up Visual Studio 2013.

img

This is telling me to open ActivityLog.xml, and hopefully an answer will be found. So I opened up that file and found some error entries:

No EditorOptionDefinition export found for the given option name: Graphics/Simple/Enable
Parameter name: optionId

For Visual Studio 2013, it’s located in the

%LOCALAPPDATA%\Microsoft\VisualStudio\12.0 folder.
For Visual Studio 2012, it’s 11.0 folder.

I renamed ComponentModelCache to ComponentModelCache.Borked and restarted Visual Studio. It started right up and without any errors.

Can’t save your table changes in SQL2008 Management Studio ?

In SQL Server 2008, when you do some changes on a table and save it you’ll get a warning message like below

Saving changes is not permitted. The changes you have made require the following tables to be dropped and re-created. You have either made changes to a table that can’t be re-created or enabled the option Prevent saving changes that require the table to be re-created.

What the… that didn’t happen to me in SQL Server 2005 nor previous versions of SQL Server. So there is definitely a behaviour change in the new management studio. Luckily this behaviour can be disabled. You just need to go to Tools -> Options then go to the Designer Page and uncheck “Prevent saving changes that require table re-creation”.

How do I remove the last character in a string in T-SQL?

I.E.

‘TEST STRING’

to return:

‘TEST STRIN’

Sample code:

1
2
3
4
5
6
7
DECLARE @String VARCHAR(100)
SET @String = 'TEST STRING'

-- Chop off the end character
SET @String = LEFT(@String, LEN(@String) - 1)

SELECT @String