ipjohnson / Grace

Grace is a feature rich dependency injection container library
MIT License
336 stars 33 forks source link

Question...How do I do this? #194

Closed scovel closed 6 years ago

scovel commented 6 years ago

I'm trying to port some code from Unity. (SolrNet container integration)

Here's the syntax..

container.RegisterType<IReadOnlyMappingManager, MemorizingMappingManager>(new InjectionConstructor(new ResolvedParameter(typeof (AttributesMappingManager))));

Another:

 var ISolrQueryExecuter = typeof (ISolrQueryExecuter<>).MakeGenericType(core.DocumentType);
            var SolrQueryExecuter = typeof (SolrQueryExecuter<>).MakeGenericType(core.DocumentType);
            string coreConnectionId = GetCoreConnectionId(core.Id);
            var registrationId = isNamed ? core.Id : null;
            container.RegisterType(
                ISolrQueryExecuter, SolrQueryExecuter, registrationId,
                new InjectionConstructor(
                    new ResolvedParameter(typeof (ISolrAbstractResponseParser<>).MakeGenericType(core.DocumentType)),
                    new ResolvedParameter(typeof (ISolrConnection), coreConnectionId),
                    new ResolvedParameter(typeof (ISolrQuerySerializer)),
                    new ResolvedParameter(typeof (ISolrFacetQuerySerializer)),
                    new ResolvedParameter(typeof (ISolrMoreLikeThisHandlerQueryResultsParser<>).MakeGenericType(core.DocumentType))));

The point seems to be to create a named (keyed?) registrations.

You get this instances like this:

var core1 = container.Resolve<ISolrOperations<Entity>>("core1");

How would you do this in Grace?

ipjohnson commented 6 years ago

Hi @scovel,

I’ll find some examples tonight showing how to do this. Essentially it’s just adding a couple WithCtorParam configurations to the Export call.

ipjohnson commented 6 years ago

I realized there was no method to register what you wanted to do so I added a new method and will do a nuget pre-release for it.

Case 1:

container.Configure(c => 
       c.Export<MemorizingMappingManager>().As<IReadOnlyMappingManager>().
         WithCtorParam<IReadOnlyMappingManager>().Use(typeof(AttributesMappingManager)));

Case 2:

if(registrationId == null)
{
  container.Configure(c => 
        c.Export(SolrQueryExecuter).As(ISolrQueryExecuter).
          WithCtorParam(typeof(ISolrConnection)).LocateWithKey(coreConnectionId));
}
else 
{
  container.Configure(c => 
        c.Export(SolrQueryExecuter).AsKeyed(ISolrQueryExecuter, registrationId).
          WithCtorParam(typeof(ISolrConnection)).LocateWithKey(coreConnectionId));
}
scovel commented 6 years ago

That is working!!!

I owe you so many beers....

So, follow-up question. I need to set an injection property at the same time. Unity was using InjectionProperty. I looked at ImportMembers but couldn't figure out how to set a specific value.

.ImportMembers(MembersThat.AreNamed("HttpWebRequestFactory"))

Looking at the property in the library there is no specific injection attributes on it, it's just a public property.

        /// <summary>
        /// HTTP request factory
        /// </summary>
        public IHttpWebRequestFactory HttpWebRequestFactory { get; set; }

Here's the Unity code:

container.RegisterType<ISolrConnection, SolrConnection>("solr" + typeof(SolrConnection), 
     new InjectionMember[] { new InjectionConstructor("http://localhost:8983/solr"),  
     new InjectionProperty("HttpWebRequestFactory", new BasicAuthHttpWebRequestFactory("user", "pass")) });

Now, why they didn't just add an overloaded constructor, I have no idea...

scovel commented 6 years ago

That is working!!!

I owe you so many beers....

So, follow-up question. I need to set an injection property at the same time. Unity was using InjectionProperty. I looked at ImportMembers but couldn't figure out how to set a specific value.

.ImportMembers(MembersThat.AreNamed("HttpWebRequestFactory"))

Looking at the property in the library there is no specific injection attributes on it, it's just a public property.

        /// <summary>
        /// HTTP request factory
        /// </summary>
        public IHttpWebRequestFactory HttpWebRequestFactory { get; set; }

Here's the Unity code:

container.RegisterType<ISolrConnection, SolrConnection>("solr" + typeof(SolrConnection), 
     new InjectionMember[] { new InjectionConstructor("http://localhost:8983/solr"),  
     new InjectionProperty("HttpWebRequestFactory", new BasicAuthHttpWebRequestFactory("user", "pass")) });

Now, why they didn't just add an overloaded constructor, I have no idea...

ipjohnson commented 6 years ago

@scovel, I think is probably another case of the container can do it but the registration method is missing for non generic.

I can add it but I may not be able to get to it till this weekend because of family obligations.

scovel commented 6 years ago

Sounds good. I finished up the rest of the port and didn't find anything else I need. Let me know when you want me to test.

Have a good weekend.

ipjohnson commented 6 years ago

Ok I've pushed out a beta to nuget with the new ImportProperty method.

scovel commented 6 years ago

The beta is working great! Thanks for your efforts again.

ipjohnson commented 6 years ago

Very cool, in 2-3 weeks I’ll plan to do an official release.

scovel commented 6 years ago

How's it going with the official release? We have a release coming up in a week or so and I'd like to change my Grace package from Beta before that happens.

Thanks,

Sean

ipjohnson commented 6 years ago

I’ll do an official release this weekend.

ipjohnson commented 6 years ago

marking as closed in release 6.4.2