I tried the free ActiveRoles Management Shell for Active Directory yesterday; it worked well for my needs.
I have read-only rights to AD at work, so my sole interest was querying AD (such as “what members are in group X"). It handles that fairly intuitively, but it does assume a basic level of PowerShell knowledge.
Iowa Code Camp is coming up (November 6, 2010 in Des Moines); register now!
I’m playing with the new features of C#/.NET 4.0; this is some code I wrote in LINQPad to try out the System.Lazy<T> class.
void Main()
{
Console.WriteLine("Running...");
Expensive one = GimmeOne;
Expensive two = GimmeOne;
if (one == two) Console.WriteLine("Same instance");
}
private static readonly Lazy<Expensive> _lazy =
new Lazy<Expensive>();
// If constructor arguments, use:
// new Lazy<Expensive>(() => new Expensive(args));
Expensive GimmeOne
{
get
{
return _lazy.Value; // thread safe
}
}
class Expensive
{
public Expensive()
{
Console.WriteLine("Creating expensive instance");
}
}
Output:
Running... Creating expensive instance Same instance
Update - October 14, 2010
The private field does not have to be static; there’s seldom a need for a true Singleton.
The other day I was creating a WinForms application, and it kept blowing up at runtime on a line that referenced Properties.Resources.SomeExistingResource with:
System.Resources.MissingManifestResourceException: Could not find any resources appropriate for the specified culture or the neutral culture. Make sure “MyNamespace.Properties.Resources.resources” was correctly embedded or linked into assembly “MyApp” at compile time, or that all the satellite assemblies required are loadable and fully signed.
A fellow developer (Phil) and I figured it out, with help from a Stack Overflow article.
There’s a literal string in Resources.Designer.cs (under Properties/Resources.resx in Solution Explorer) that’s automatically updated based on the value of the Default Namespace in the project properties (Application tab) in Visual Studio 2010. Normally the namespace of this auto-generated Resources class is kept synchronized with this value. In my case I was using a custom project template, and apparently they got out of sync.
Timwi and others offer alternate solutions in the Stack Overflow article linked above. In my case I just had to change the Default Namespace to match the namespace in the file.
C#/.NET 4.0 has some nice features, including the Tuple classes. While generic tuples do not override the == operator, they do override Equals. This allows tuples composed of primitive types to be compared.
An interesting use of this is in refactoring LINQ queries, some of which can get quite long. The problem is that multiple-key joins are generally performed with anonymous types (because they override Equals/GetHashCode to compare properties), but anonymous types cannot be returned from methods (unless the return type is dynamic). Queries may also select anonymous types.
Tuples provide a neat solution to this. Here is a contrived example, which assumes legacy data with multi-column keys. (Note that this is LINQ to Objects, not LINQ to SQL.) I probably would not refactor to this degree in production code, as the Item1/Item2 portions are unclear. Note the elegant join in GetOrdersWithCustomers, though.
internal class Program
{
private static void Main()
{
IEnumerable<Customer> customers = GetCustomers();
IEnumerable<Order> orders = GetOrders();
IEnumerable<Item> items = GetItems();
/* Original:
var query =
from order in orders
join customer in customers
on
new
{
order.CustomerType,
order.CustomerId
}
equals
new
{
CustomerType = customer.Type,
CustomerId = customer.Id
}
join item in items
on order.Id equals item.OrderId
select
new
{
OrderId = order.Id,
CustomerName = customer.Name,
item.Product
};
*/
// Refactored:
var ordersWithCustomers =
GetOrdersWithCustomers(orders, customers);
var query =
from x in ordersWithCustomers
join item in items
on x.Item1.Id equals item.OrderId
select
new
{
OrderId = x.Item1.Id,
CustomerName = x.Item2.Name,
item.Product
};
foreach (var record in query)
{
Console.WriteLine(record);
}
}
private static IEnumerable<Tuple<Order, Customer>>
GetOrdersWithCustomers(
IEnumerable<Order> orders,
IEnumerable<Customer> customers)
{
return
from order in orders
join customer in customers
on order.GetCustomerKey()
equals customer.GetKey()
select
new Tuple<Order, Customer>
(order, customer);
}
private static IEnumerable<Item> GetItems()
{
return
new List<Item>
{
new Item
{
OrderId = 10,
Product = "TenOne"
},
new Item
{
OrderId = 10,
Product = "TenTwo"
},
new Item
{
OrderId = 20,
Product = "TwentyOne"
}
};
}
private static IEnumerable<Order> GetOrders()
{
return
new List<Order>
{
new Order
{
Id = 10,
CustomerType = "A",
CustomerId = 1
},
new Order
{
Id = 20,
CustomerType = "A",
CustomerId = 2
}
};
}
private static IEnumerable<Customer> GetCustomers()
{
return
new List<Customer>
{
new Customer
{
Type = "A",
Id = 1,
Name = "Bob"
},
new Customer
{
Type = "B",
Id = 1,
Name = "Hobo"
},
new Customer
{
Type = "A",
Id = 2,
Name = "Bill"
},
new Customer
{
Type = "B",
Id = 2,
Name = "Shotgun"
}
};
}
}
internal class Customer
{
public string Type { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public Tuple<string, int> GetKey()
{
return new Tuple<string, int>(Type, Id);
}
}
internal class Order
{
public int Id { get; set; }
public string CustomerType { get; set; }
public int CustomerId { get; set; }
public Tuple<string, int> GetCustomerKey()
{
return new Tuple<string, int>
(CustomerType, CustomerId);
}
}
internal class Item
{
public int OrderId { get; set; }
public string Product { get; set; }
} Microsoft chose to bundle FxCop v10 with the Windows 7 SDK, which is pretty huge. Matthew1471 offers an excellent tip on his blog: .NET FxCop 10 Install from CAB. This lets you extract the small setup file and just install FxCop! It works fine.
What’s more, you can install FxCop to a folder under your source control tree, check in the folder, then uninstall FxCop. This lets all your developers (and your build server) run FxCop without installing it. This also works; I tried it today with TeamCity. You just have to change the FxCop installation root.
EDIT: Kriz mentioned an issue in the comments; other people have also encountered this. I don’t know of anyone at work who has, though. The missing interop assembly doesn’t appear to install in the GAC with Visual Studio, either. I don’t have an answer, but it’s working for us.
Development Central is the blog of Bill Sorensen, a professional software developer. Much of this will relate to C#, .NET, and OOP in general.
Disclaimer
These postings are provided "AS IS" with no warranties and confer no rights.