var assemblyTypes = assembly.GetTypes();
foreach (Type type in assemblyTypes)
{
if (type.IsAbstract)
continue;
foreach (Type i in type.GetInterfaces())
{
if (i.Assembly.GetCustomAttributes(typeof(DbLinqAttribute), false).Length > 0)
{
IList<Type> types;
if (!interfaceImplementations.TryGetValue(i, out types))
interfaceImplementations[i] = types = new List<Type>();
types.Add(type);
}
}
}
This is less than ideal for two reasons:
// within DbLinq.dll:
[AttributeUsage(AttributeTargets.Assembly)]
public class DbLinqProviderAttribute {
public DbLinqProviderAttribute(Type providerType);
public Type ProviderType {get;}
}
// within e.g. DbLinq.Sqlite.dll
[assembly:DbLinqProvider(typeof(SqliteVendor))]
This turns the O(n*m) (n=types, m=interfaces for each type) algorithm used in ReflectonObjectFactory.Parse() into an O(1) algorithm, improving execution time and lowering memory requirements (as we don't need to allocate a potentially large array from Assembly.GetTypes(), etc.).In this case, we're not providing a connection string (deliberately, as we don't actually want to connect to a database), and thus there is no explicit reference to the provider that we want to test. This is undesirable; it's only acceptable for now because the default provider is the SqlServer provider, which is what I was testing, but this should not remain the situation for long.return new DataContext(new NullConnection(), new AttributeMappingSource());
private void Init(IDatabaseContext databaseContext, MappingSource mappingSource, IVendor vendor)
{
if (databaseContext == null)
throw new ArgumentNullException("databaseContext");
_VendorProvider = ObjectFactory.Get<IVendorProvider>();
if (vendor == null)
Vendor = _VendorProvider.FindVendorByProviderType(typeof(SqlClient.Sql2005Provider));
else
Vendor = vendor;
Non-SqlServer providers aren't supported because vendor will be null, thus prompting Init() to try to find the SqlClient.Sql2005Provider provider. Oops.As I posted some time ago in this list, Linq to Sql author, Matt Warren blog
contains sample about replacing default MS Linq-To-Sql provider with
other linq provider implementing provider interface.
Initially MS desided to make this interface public but later desicion was to
change it to internal.
Andrus Moor.
I assume you mean this entry:
I think it should be fairly obvious that we don't want to reimplement
Microsoft's internal interfaces, and that we should come up with a
public, well supported mechanism here. Using TransparentProxy's and
Reflection to muck about with private code is NOT the way to go.
- Jon
Regarding the fact of loading a given vendor, without referencing it, the following threads were talking about it:
http://groups.google.com/group/dblinq/browse_thread/thread/9e3b0ffa5f2d7e1f/6716fb3496c10b5f
http://groups.google.com/group/dblinq/browse_thread/thread/ce397e5f58b36a12/d7378bd1c401957a
I had in mind that the IDbConnection.ConnectionString was a string, so it could be handled the same way... :)